Signatur
Beschreibung
Die Methode segment() teilt den übergebenen String anhand der Regeln des Unicode-Standards (UAX #29) und der beim Konstruktor angegebenen Locale in sinnvolle Einheiten auf. Welche Einheiten das sind, hängt von der Option granularity des Segmenters ab: "grapheme" (vom Nutzer wahrgenommene Zeichen, Standard), "word" (Wörter samt Leerzeichen und Satzzeichen) oder "sentence" (Sätze).
Der Rückgabewert ist ein Segments-Objekt. Es ist iterierbar (for...of, Spread-Syntax, Array.from()) und liefert pro Segment ein Datenobjekt mit den Eigenschaften segment (der Teilstring), index (Startposition in UTF-16-Codeeinheiten) und input (der ursprüngliche String). Bei Wort-Granularität kommt zusätzlich isWordLike hinzu, das angibt, ob es sich um ein „echtes“ Wort (Buchstaben, Zahlen, Ideogramme) oder um Leerzeichen/Satzzeichen handelt. Mit segments.containing(index) lässt sich außerdem gezielt das Segment an einer bestimmten Position abfragen.
Einsatzgebiete sind z. B. korrektes Zählen sichtbarer Zeichen (Emojis mit Hauttönen, Flaggen, kombinierende Akzente), Wortzählung auch in Sprachen ohne Leerzeichen wie Japanisch, Chinesisch oder Thai, das Kürzen von Texten ohne zerbrochene Zeichen sowie Cursor-Navigation in Editoren. Einfache Ansätze wie str.split(" ") oder [...str] versagen in diesen Fällen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $input Pflicht | string | Der zu segmentierende Text. Nicht-String-Werte werden per String() umgewandelt (undefined wird zu "undefined"). |
Rückgabewert
Segments-Objekt. Jede Iteration liefert { segment, index, input } bzw. bei granularity: "word" zusätzlich isWordLike. Die Methode containing(index) gibt das Segment an einer Position oder undefined zurück.Beispiele
Sichtbare Zeichen korrekt zählen (Grapheme)
const text = "Café 👍🏽🇩🇪";
const segmenter = new Intl.Segmenter("de", { granularity: "grapheme" });
const graphemes = [...segmenter.segment(text)].map((s) => s.segment);
console.log(text.length); // UTF-16-Codeeinheiten
console.log([...text].length); // Codepoints
console.log(graphemes.length); // wahrgenommene Zeichen
console.log(graphemes);
Wörter zählen – auch bei Japanisch
const countWords = (text, locale) => {
const segmenter = new Intl.Segmenter(locale, { granularity: "word" });
return [...segmenter.segment(text)].filter((s) => s.isWordLike).length;
};
console.log(countWords("Hallo Welt, wie geht's?", "de"));
console.log(countWords("吾輩は猫である。", "ja"));
Text sicher kürzen ohne Emojis zu zerbrechen
const truncate = (text, maxChars, locale = "de") => {
const segmenter = new Intl.Segmenter(locale, { granularity: "grapheme" });
const parts = [];
for (const { segment } of segmenter.segment(text)) {
if (parts.length === maxChars) return parts.join("") + "…";
parts.push(segment);
}
return parts.join("");
};
console.log(truncate("Familie: 👨👩👧👦 im Urlaub", 10));
Satz an Cursorposition finden mit containing()
const text = "Das ist Satz eins. Hier kommt Satz zwei! Und drei?";
const segmenter = new Intl.Segmenter("de", { granularity: "sentence" });
const segments = segmenter.segment(text);
const cursor = 25;
const hit = segments.containing(cursor);
console.log(hit.segment, hit.index);
console.log(segments.containing(999));
// Wichtig · Fallstricke
indexzählt UTF-16-Codeeinheiten, nicht Grapheme – passend zuString.prototype.slice(), aber nicht zur sichtbaren Zeichenposition.- Das
Segments-Objekt ist kein Array:length,map()oderfilter()gibt es nicht. Zuerst mit[...segments]oderArray.from()umwandeln. - Die Segmentierung erfolgt lazy beim Iterieren; bei sehr langen Texten lieber mit
for...ofarbeiten und früh abbrechen, statt alles in ein Array zu kopieren. isWordLikeist nur beigranularity: "word"vorhanden, sonstundefined.- Ergebnisse für Wort- und Satzgrenzen können sich zwischen Engines und Versionen unterscheiden (ICU-Daten, Wörterbücher für CJK/Thai). Satzerkennung stolpert oft über Abkürzungen wie „z. B.“.
- Kompatibilität: Firefox unterstützt
Intl.Segmentererst ab Version 125 (2024). Für ältere Umgebungen pertypeof Intl.Segmenter === "function"prüfen und ggf. ein Polyfill (z. B. von FormatJS) einsetzen. In Node.js ist volle ICU-Unterstützung (Standard seit Node 13) nötig.