Java · Unicode Segmentation

Unicode Segmentation

6.0.0-rc.1 · 91a27bdd

The segmentation primitive is allocation-free: it fills the caller’s array with segment lengths and returns the count. Segments tile the text, so each starts where the previous one ended.

int decoded = StringZilla.decode(text, codepoints); // fill an int[]; ill-formed or truncated -> U+FFFD

long[] lengths = new long[64];
int count = StringZilla.segment(text, 0, text.length, StringZilla.SegmentKind.WORDS, lengths); // UAX-29
int start = 0;
for (int segment = 0; segment < count; segment++) {
    use(text, start, (int) lengths[segment]);
    start += (int) lengths[segment];
}

Codepoints count scalar values, not bytes or UTF-16 chars. Segmentation tiles the text — every byte belongs to exactly one segment — and a grapheme cluster can span several codepoints.

StringZilla.countRunes("你好世界".getBytes(UTF_8)); // 4 codepoints
StringZilla.countRunes("Hello🌍".getBytes(UTF_8));  // 6 — the astral emoji is one scalar

for (MemorySegment cluster : StringZilla.graphemes("👍🏽🇺🇸".getBytes(UTF_8))) use(cluster);   // 👍🏽 (emoji + skin tone), 🇺🇸 (flag)
for (MemorySegment word : StringZilla.words("Hello, 世界".getBytes(UTF_8))) use(word);      // Latin run, then CJK run