Парсеры

Парсинг данных в Globalize строится вокруг преобразования строкового представления локализованных значений в машинные типы JavaScript с учётом правил конкретной локали. Основная сложность заключается в том, что одно и то же значение может иметь различные визуальные формы в разных регионах: числа используют разные разделители, даты имеют отличающиеся порядки компонентов, а денежные значения включают локальные обозначения валют и пробелы форматирования.

В основе работы парсеров лежит связка между форматированием и обратным преобразованием. Если форматтер отвечает за превращение числа или даты в строку, то парсер решает обратную задачу — восстановление исходного значения из локализованного текста.

Парсеры в Globalize опираются на данные CLDR (Unicode Common Locale Data Repository), которые содержат:

  • правила форматирования чисел;
  • шаблоны дат и времени;
  • обозначения валют;
  • символы разделителей и группировок;
  • локальные особенности интерпретации значений.

Ключевой принцип: парсинг невозможен без предварительно загруженных CLDR-данных, соответствующих используемой локали.

Парсинг чисел

Парсинг чисел — одна из базовых операций, поскольку числовые значения часто вводятся пользователем в локализованном формате.

В разных локалях различаются:

  • десятичный разделитель (. или ,);
  • разделитель групп разрядов (, или пробел);
  • правила отрицательных чисел (минус, скобки);
  • использование неразрывных пробелов.

В Globalize для этого используется метод:

Globalize(locale).parseNumber(string);

Пример логики обработки:

  • строка "1,234.56" в en-US интерпретируется как 1234.56;
  • строка "1 234,56" в ru-RU интерпретируется как 1234.56.

Парсер выполняет:

  1. удаление группировочных символов;
  2. замену локального десятичного разделителя на точку;
  3. преобразование результата в число JavaScript.

Особенность заключается в строгой зависимости от локали: одна и та же строка может быть корректной в одной локали и некорректной в другой.

Парсинг валют

Парсинг валютных значений расширяет числовой парсинг за счёт обработки символов валют и их расположения относительно числа.

Форматы могут отличаться:

  • $1,000.00 (символ перед числом);
  • 1 000,00 € (символ после числа);
  • USD 1,000.00 (код валюты);
  • локализованные пробелы между символами.

Метод:

Globalize(locale).parseCurrency(string);

Процесс включает:

  • определение валютного символа или кода;

  • извлечение числовой части;

  • обработку пробелов и неразрывных символов;

  • нормализацию результата в структуру вида:

    • значение (number);
    • идентификатор валюты (currency code).

Парсер валюты должен учитывать неоднозначность: некоторые символы могут пересекаться с математическими обозначениями или текстом.

Парсинг дат и времени

Парсинг дат значительно сложнее числового, поскольку зависит не только от локали, но и от множества форматов представления:

  • MM/dd/yyyy (США);
  • dd.MM.yyyy (Россия, Германия);
  • yyyy-MM-dd (ISO-подобные форматы);
  • словесные формы месяцев.

Globalize использует:

Globalize(locale).parseDate(string, options);

Разбор структуры даты

Парсер даты выполняет последовательные этапы:

  1. Сопоставление строки с шаблонами CLDR.
  2. Определение порядка компонентов (день, месяц, год).
  3. Интерпретация разделителей (., /, -, пробелы).
  4. Обработка времени (часы, минуты, секунды, AM/PM).
  5. Учёт локальных особенностей календаря.

Особую сложность представляют:

  • неоднозначные форматы (01/02/2020 — январь или февраль);
  • пропущенные компоненты (например, только дата без времени);
  • 12/24-часовые системы.

Нормализация результата

После разбора строка преобразуется в объект Date. При этом важно учитывать, что JavaScript Date хранит значение в UTC-основанной внутренней форме, а локаль влияет только на интерпретацию входной строки.

Стратегии парсинга

Парсеры Globalize используют несколько стратегий сопоставления:

Строгий парсинг

Ожидает полное соответствие формату локали. Любое отклонение приводит к ошибке или null.

Гибкий парсинг

Позволяет:

  • игнорировать лишние пробелы;
  • обрабатывать частично заполненные строки;
  • принимать альтернативные разделители.

Шаблонный парсинг

Использует заранее определённые CLDR-шаблоны для сопоставления строки с возможными форматами.

Зависимость от CLDR-данных

Парсинг в Globalize невозможен без загрузки соответствующих наборов данных:

  • cldr-numbers-full — для чисел;
  • cldr-dates-full — для дат;
  • cldr-currencies-full — для валют.

Отсутствие данных приводит к невозможности корректного разбора даже формально правильных строк.

CLDR определяет:

  • символы разделителей;
  • порядок компонентов даты;
  • локальные названия месяцев;
  • форматы валют.

Ошибки парсинга

Типичные проблемы при работе с парсерами:

Несоответствие локали

Строка сформирована в одной локали, а парсится в другой.

Неполные CLDR-данные

Отсутствие необходимых сегментов данных приводит к невозможности распознавания формата.

Неоднозначные форматы

Строки, которые могут быть интерпретированы несколькими способами.

Нестандартные пользовательские вводы

Дополнительные символы, сокращения или опечатки, не предусмотренные CLDR.

Производительность парсеров

Парсинг в Globalize включает:

  • поиск шаблонов;
  • сопоставление строк;
  • обработку локализованных символов.

Наиболее затратной операцией является парсинг дат, так как он требует анализа множества возможных шаблонов.

Оптимизация достигается за счёт:

  • предварительной загрузки CLDR;
  • ограничения набора поддерживаемых форматов;
  • кэширования результатов локалей.

Согласование форматирования и парсинга

Ключевая особенность Globalize заключается в симметрии операций:

  • форматирование формирует строку;
  • парсинг восстанавливает значение.

Однако полная обратимость не гарантируется, поскольку:

  • форматирование может терять детали (например, ведущие нули);
  • локализованные представления неоднозначны;
  • пользовательский ввод может отличаться от стандартного формата.

Практическая модель работы парсеров

Логика работы можно представить как последовательность:

  1. Определение локали.
  2. Загрузка CLDR-данных.
  3. Выбор соответствующего парсера (число, дата, валюта).
  4. Применение правил локали.
  5. Нормализация результата.
  6. Возврат значения или ошибки.

Такой подход обеспечивает предсказуемость обработки данных в многоязычных интерфейсах, где ввод пользователя не ограничен единым форматом представления информации.