Start · Sprachen · JavaScript · Referenz · Intl.Segmenter.prototype.segment()

Intl.Segmenter.prototype.segment()

Methode

Zerlegt einen String gemäß Locale und Granularität des <code>Intl.Segmenter</code> in Grapheme, Wörter oder Sätze und liefert ein iterierbares <code>Segments</code>-Objekt.

seit JavaScript ES2022 (Baseline seit 2024: Chrome 87, Safari 14.1 Kategorie: method-property

Signatur

Intl.Segmenter.prototype.segment(input)

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

Typ
Segments
Beschreibung
Ein iterierbares 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);
11 9 7 ["C", "a", "f", "é", " ", "👍🏽", "🇩🇪"]

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"));
4 4 (abhängig von den Wörterbuchdaten der Engine)

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));
Familie: 👨‍👩‍👧‍👦…

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));
Hier kommt Satz zwei! 19 undefined

// Wichtig · Fallstricke

  • index zählt UTF-16-Codeeinheiten, nicht Grapheme – passend zu String.prototype.slice(), aber nicht zur sichtbaren Zeichenposition.
  • Das Segments-Objekt ist kein Array: length, map() oder filter() gibt es nicht. Zuerst mit [...segments] oder Array.from() umwandeln.
  • Die Segmentierung erfolgt lazy beim Iterieren; bei sehr langen Texten lieber mit for...of arbeiten und früh abbrechen, statt alles in ein Array zu kopieren.
  • isWordLike ist nur bei granularity: "word" vorhanden, sonst undefined.
  • 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.Segmenter erst ab Version 125 (2024). Für ältere Umgebungen per typeof 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.