Перенос слов в интерфейсах, работающих с многоязычным контентом, определяется не только правилами конкретного языка, но и моделью представления текста в Unicode. Прямое разбиение строки по пробелам приводит к некорректному поведению для языков без пробелов, сложных графемных кластеров и контекстно-зависимых правил разбиения.
В JavaScript задачи сегментации текста и подготовки его к переносу
частично решаются через Intl API, в первую очередь
через механизм Intl.Segmenter, основанный на Unicode Text
Segmentation Standard (UAX #29).
Любая логика переноса строк опирается на определение единиц текста:
Простейший подход:
const words = text.split(" ");
Такой метод не учитывает:
Intl.Segmenter предоставляет стандартизированную
сегментацию текста с учетом локали и типа разбиения.
const segmenter = new Intl.Segmenter("en", { granularity: "word" });
const segments = segmenter.segment("Hello world!");
for (const { segment, isWordLike } of segments) {
console.log(segment, isWordLike);
}
Результат содержит не просто строки, а структурированные сегменты:
segment — фрагмент текстаindex — позиция в исходной строкеisWordLike — признак словоподобного сегментаconst segmenter = new Intl.Segmenter("ja", { granularity: "grapheme" });
Используется для корректного отображения символов:
Графемная сегментация важна, когда перенос не должен разрывать визуально неделимый символ.
const segmenter = new Intl.Segmenter("ru", { granularity: "word" });
Позволяет определить границы слов для:
<wbr>const segmenter = new Intl.Segmenter("en", { granularity: "sentence" });
Используется в случаях:
Перенос текста в веб-интерфейсах определяется несколькими уровнями:
overflow-wrap, word-break,
hyphens)Intl.Segmenter находится выше CSS по уровню абстракции,
поскольку позволяет формировать текст до рендеринга.
Одно из практических применений сегментации — вставка мягких точек переноса.
<wbr>const segmenter = new Intl.Segmenter("en", { granularity: "word" });
function insertBreaks(text) {
return [...segmenter.segment(text)]
.map(s => s.segment)
.join("<wbr>");
}
Такой подход позволяет браузеру переносить строки в корректных местах без нарушения целостности слов.
В языках вроде китайского и японского границы слов не совпадают с пробелами:
const segmenter = new Intl.Segmenter("zh", { granularity: "word" });
const text = "今天的天气很好";
Без сегментации разбиение строки невозможно выполнить корректно.
Некоторые письменности требуют учета контекста символов:
Intl.Segmenter учитывает правила Unicode, а не
упрощенные эвристики.
Один видимый символ может состоять из нескольких Unicode-кодов:
é = e + U+0301Графемная сегментация предотвращает разрыв таких конструкций при переносе.
const segmenter = new Intl.Segmenter("en", { granularity: "grapheme" });
const text = "???? family";
console.log([...segmenter.segment(text)]);
JavaScript-сегментация используется совместно с CSS:
.text {
overflow-wrap: break-word;
word-break: normal;
hyphens: auto;
}
Сценарии:
const segmenter = new Intl.Segmenter(locale, { granularity: "word" });
const segments = [...segmenter.segment(text)];
const html = segments
.map(s => `<span>${s.segment}</span>`)
.join("<wbr>");
HTML получает управляемые точки переноса без потери семантики слов.
Intl.Segmenter оптимизирован на уровне движков:
Однако частое пересоздание сегментера нежелательно:
// неэффективно
function bad(text) {
const s = new Intl.Segmenter("en", { granularity: "word" });
return [...s.segment(text)];
}
Оптимальная модель:
const segmenter = new Intl.Segmenter("en", { granularity: "word" });
function good(text) {
return [...segmenter.segment(text)];
}
Локаль влияет на:
new Intl.Segmenter("en-US", { granularity: "word" });
new Intl.Segmenter("de", { granularity: "word" });
Различия особенно заметны в составных словах немецкого языка и сокращениях английского.
Дополнительный механизм — символ мягкого переноса:
\u00AD (soft hyphen)const text = "international\u00ADization";
Он отображается только при переносе строки.
Несмотря на возможности Intl API:
На практике применяется сочетание:
Intl.Segmenter — логическая сегментацияhyphens — типографика<wbr> — управляемые точки переносаТакая модель позволяет обеспечить корректное поведение текста в многоязычных интерфейсах без потери семантики и визуальной целостности.