Signatur
Beschreibung
Die Methode [Symbol.iterator]() von Segments-Instanzen implementiert das iterierbare Protokoll. Ein Segments-Objekt entsteht durch Intl.Segmenter.prototype.segment(string). Durch den Iterator kann man es direkt mit for...of, dem Spread-Operator [...segments], Array.from() oder Destrukturierung verwenden.
Jeder Iterationsschritt liefert ein Segment-Datenobjekt mit diesen Eigenschaften:
segment– der Teilstring des Segments (Graphem, Wort oder Satz)index– der Startindex des Segments im ursprünglichen String (in UTF-16-Codeeinheiten)input– der vollständige segmentierte StringisWordLike– nur beigranularity: "word":true, wenn das Segment ein „Wort“ ist (Buchstaben, Zahlen), sonstfalsefür Leerzeichen und Satzzeichen. Bei anderen Granularitäten ist esundefined.
Den Iterator braucht man immer dann, wenn man Text sprachabhängig korrekt zerlegen will, z. B. um sichtbare Zeichen einschließlich Emojis und Kombinationszeichen zu zählen, Wörter in Sprachen ohne Leerzeichen (Japanisch, Thai, Chinesisch) zu trennen oder Text in Sätze aufzuteilen. Die Segmentierung passiert dabei lazy: Die Segmente werden erst beim Weiterschalten des Iterators berechnet.
Rückgabewert
Iterator.prototype), dessen next()-Methode nacheinander die Segment-Datenobjekte liefert.Beispiele
Sichtbare Zeichen (Grapheme) korrekt zählen
const segmenter = new Intl.Segmenter('de', { granularity: 'grapheme' });
const text = 'Hallo 👋🏽 Welt 👨👩👧';
// Spread nutzt intern [Symbol.iterator]()
const graphemes = [...segmenter.segment(text)];
console.log(text.length); // UTF-16-Codeeinheiten
console.log(graphemes.length); // tatsächlich sichtbare Zeichen
Wörter mit for...of und isWordLike zählen
const segmenter = new Intl.Segmenter('de', { granularity: 'word' });
const text = 'Das ist ein Test, oder nicht?';
const words = [];
for (const { segment, isWordLike } of segmenter.segment(text)) {
// Leerzeichen und Satzzeichen überspringen
if (isWordLike) words.push(segment);
}
console.log(words);
console.log(`Wortanzahl: ${words.length}`);
Japanischen Text ohne Leerzeichen in Wörter zerlegen
const segmenter = new Intl.Segmenter('ja', { granularity: 'word' });
const text = '吾輩は猫である。';
const words = Array.from(segmenter.segment(text), (s) => s.segment);
console.log(words.join(' | '));
Iterator manuell verwenden und Satzindizes ermitteln
const segmenter = new Intl.Segmenter('de', { granularity: 'sentence' });
const segments = segmenter.segment('Erster Satz. Zweiter Satz! Dritter?');
const it = segments[Symbol.iterator]();
let result = it.next();
while (!result.done) {
const { segment, index } = result.value;
console.log(index, JSON.stringify(segment));
result = it.next();
}
// Wichtig · Fallstricke
- Kompatibilität:
Intl.Segmenterist in Chrome/Edge 87+, Safari 14.1+, Node.js 16+ verfügbar, in Firefox aber erst ab Version 125 (April 2024). Für ältere Umgebungen braucht man eine Feature-Erkennung ('Segmenter' in Intl) oder ein Polyfill. - Die genaue Segmentierung, vor allem bei Wörtern, hängt von den ICU-Daten der jeweiligen Engine ab. Die Ergebnisse können sich zwischen Browsern und Versionen leicht unterscheiden. Verlasse dich in Tests also nicht auf exakte Wortgrenzen.
indexzählt UTF-16-Codeeinheiten, nicht Grapheme. Es passt deshalb zuString.prototype.slice(), aber nicht zur Position in[...str].- Jeder Aufruf von
[Symbol.iterator]()erzeugt einen neuen Iterator. EinSegments-Objekt lässt sich also mehrfach durchlaufen, ein einzelner Iterator ist nach dem Durchlauf aber verbraucht. isWordLikeist nur beigranularity: 'word'gesetzt, sonstundefined.- Performance: Bei sehr langen Texten ist
for...ofmit frühembreakgünstiger als[...segments], weil die Segmente lazy berechnet werden. Für gezielte Abfragen an einer Position gibt esSegments.prototype.containing(index).