В библиотеке Globalize работа с форматированием строк опирается на правила ICU MessageFormat и CLDR. Одним из ключевых аспектов становится корректное экранирование символов, которые имеют синтаксическое значение в шаблонах сообщений, форматах чисел и дат. Нарушение этих правил приводит к ошибкам парсинга, некорректной интерполяции или полному разрушению структуры сообщения.
В системе сообщений Globalize выделяется набор символов, интерпретируемых не как текст, а как управляющие конструкции:
{ } — обозначают вставку переменных и
выражений;' — используется для экранирования и
управления режимом интерпретации текста;select, plural,
offset) — зависят от контекста внутри фигурных блоков;Фигурные скобки являются основным элементом интерполяции:
Globalize.formatMessage(
"messages",
"Привет, {name}!"
);
Без корректного экранирования любые дополнительные фигурные скобки вне синтаксиса интерполяции приводят к ошибке разбора строки.
Одинарная кавычка в ICU MessageFormat выполняет двойную функцию: она включает и выключает режим буквального текста. Поэтому неправильное использование кавычек изменяет структуру сообщения.
Основные правила:
Пример корректного использования:
Globalize.formatMessage(
"messages",
"It''s a simple message"
);
Здесь последовательность '' интерпретируется как один
символ '.
Пример переключения режима литерала:
Globalize.formatMessage(
"messages",
"Start '{literal text}' end"
);
В данном случае блок {literal text} не интерпретируется
как переменная.
Фигурные скобки используются исключительно для подстановки значений. Любая неэкранированная пара скобок рассматривается как выражение.
Globalize.formatMessage(
"messages",
"Balance: {amount} USD"
);
Если требуется отобразить символы { и } как
часть текста, используется экранирование через кавычки:
Globalize.formatMessage(
"messages",
"Braces example: '{' and '}'"
);
В ICU-логике символы внутри одинарных кавычек не участвуют в синтаксическом разборе.
Внутри конструкций plural и select
синтаксис становится более чувствительным к символам:
Globalize.formatMessage(
"messages",
"{count, plural, one {# item} other {# items}}"
);
Символ # имеет специальное значение — подстановка
текущего числового значения. При необходимости отображения символа
# как текста используется экранирование через кавычки:
Globalize.formatMessage(
"messages",
"{count, plural, one {'#' item} other {'#' items}}"
);
Без кавычек символ # преобразуется в значение
count, что меняет смысл строки.
Помимо message patterns, экранирование требуется в форматах чисел и процентов, где шаблоны используют специальные знаки:
0 — обязательная цифра;# — необязательная цифра;. — десятичный разделитель;, — разделитель групп;% — преобразование в проценты;‰ — промилле.Пример форматирования:
Globalize.numberFormatter({ maximumFractionDigits: 2 })(1234.567);
При необходимости отображения символов # или
0 как литералов используется экранирование через обратный
слэш в формате шаблона чисел:
Globalize.numberFormatter({
raw: "#0.00"
});
Для вывода символов как текста применяется:
'#'0.00
Форматы дат используют токены:
y — год;M — месяц;d — день;E — день недели;h, H — часы.Любые буквенные последовательности, не являющиеся токенами, должны быть защищены кавычками.
Globalize.dateFormatter({ date: "yyyy 'year' MM 'month' dd 'day'" });
Без кавычек текстовые части интерпретируются как потенциальные токены и могут привести к ошибке или искажению результата.
Наиболее частые источники ошибок связаны с комбинацией ICU-синтаксиса и текстовых данных:
# вне контекста pluralПример некорректного шаблона:
"Total: {count} items #final"
Символ #final может быть воспринят как часть синтаксиса
plural, если находится внутри соответствующего блока.
В сложных сообщениях применяется комбинация кавычек и управляющих конструкций:
Globalize.formatMessage(
"messages",
"{count, plural, one {'Item: #' item} other {'Items: #' items}}"
);
Здесь одновременно:
#;При нарушении правил экранирования происходит:
Типичный пример сбоя:
"Hello {name"
Отсутствие закрывающей скобки делает выражение недопустимым ICU-паттерном.
Несмотря на то, что Globalize опирается на CLDR, правила экранирования остаются едиными для всех локалей. Отличия наблюдаются только в:
Символы ICU и механизмы экранирования сохраняют одинаковую семантику независимо от языка, что обеспечивает предсказуемость обработки сообщений.