How Intl.Segmenter Breaks Strings in JavaScript
The Intl.Segmenter API is a built-in JavaScript object
that provides locale-sensitive text segmentation, enabling developers to
split strings into meaningful units such as graphemes (characters),
words, or sentences. Unlike standard string manipulation methods like
split() or regular expressions, Intl.Segmenter
respects language-specific boundary rules, making it an essential tool
for properly handling multilingual text, complex emojis, and non-spaced
languages such as Japanese, Chinese, or Thai.
Understanding the Syntax
To use the API, instantiate a new Intl.Segmenter
instance by passing a locale identifier (or array of locales) and an
options object defining the segmentation granularity.
const segmenter = new Intl.Segmenter(locale, { granularity: 'grapheme' | 'word' | 'sentence' });The granularity property accepts three values: *
'grapheme': Splits text into individual visual characters
(properly handling combined emojis and diacritics). *
'word': Splits text into words, punctuation, and whitespace
boundaries. * 'sentence': Splits text into full sentences
based on linguistic conventions.
Calling segmenter.segment(inputString) returns an
iterable Segments object containing the segmented data.
Breaking Strings into Words
Splitting text by simple spaces using string.split(' ')
fails in languages that do not use spaces and often leaves punctuation
attached to words. The word granularity solves this by
identifying semantic word boundaries and providing metadata to
distinguish words from punctuation and whitespace.
Each segment returned in word mode contains: * segment:
The extracted substring. * index: The zero-based character
index where the segment begins. * input: The original
source string. * isWordLike: A boolean flag indicating
whether the segment is an actual word (true) or
whitespace/punctuation (false).
Example: Extracting Words
const text = "Hello, world! How are you doing today?";
const segmenter = new Intl.Segmenter('en', { granularity: 'word' });
const segments = segmenter.segment(text);
// Filter out spaces and punctuation using isWordLike
const words = Array.from(segments)
.filter(segment => segment.isWordLike)
.map(segment => segment.segment);
console.log(words);
// Output: ["Hello", "world", "How", "are", "you", "doing", "today"]Handling Non-Spaced Languages
Intl.Segmenter uses language dictionaries and break
rules defined by the Unicode standard to split text accurately without
spaces.
const japaneseText = "今日は良い天気ですね。";
const jpSegmenter = new Intl.Segmenter('ja', { granularity: 'word' });
const jpWords = Array.from(jpSegmenter.segment(japaneseText))
.filter(s => s.isWordLike)
.map(s => s.segment);
console.log(jpWords);
// Output: ["今日", "は", "良い", "天気", "です", "ね"]Breaking Strings into Sentences
Splitting sentences with basic regular expressions often leads to
errors when encountering abbreviations (e.g., “Dr.”, “e.g.”, “inc.”) or
decimal numbers. The sentence granularity applies Unicode
sentence boundary algorithms (UAX #29) tailored to the specified
locale.
Example: Extracting Sentences
const paragraph = "Dr. Smith arrived at 6 a.m. He was very tired! Did he sleep well?";
const sentenceSegmenter = new Intl.Segmenter('en', { granularity: 'sentence' });
const sentenceSegments = sentenceSegmenter.segment(paragraph);
for (const { segment, index } of sentenceSegments) {
console.log(`[Index ${index}]: ${segment.trim()}`);
}
// Output:
// [Index 0]: Dr. Smith arrived at 6 a.m.
// [Index 28]: He was very tired!
// [Index 47]: Did he sleep well?Finding a Specific Segment by Index
The Segments object includes a
.containing(index) method. This method allows you to
retrieve the exact segment that contains a specified character position,
which is useful for text editors, cursor navigation, and highlight
tools.
const text = "The quick brown fox.";
const segmenter = new Intl.Segmenter('en', { granularity: 'word' });
const segments = segmenter.segment(text);
// Find the word under index 5 (inside the word "quick")
const currentSegment = segments.containing(5);
console.log(currentSegment);
// Output: { segment: "quick", index: 4, input: "The quick brown fox.", isWordLike: true }