Пользовательские regex-маски

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

Регулярная маска в Inputmask фактически заменяет посимвольное сопоставление шаблона на проверку всего значения или его части через регулярное выражение. Это меняет поведение ввода: вместо пошагового заполнения фиксированных слотов применяется проверка соответствия строки заданному правилу.


Режим regex в Inputmask

В Inputmask поддерживается отдельный alias regex, который предназначен для работы с регулярными выражениями.

Базовая форма подключения:

import Inputmask from "inputmask";

Inputmask({
  regex: "[0-9]*"
}).mask(document.querySelector("input"));

В данном режиме маска интерпретирует входные данные через регулярное выражение, заданное в параметре regex.

Особенности режима regex

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

Различие между mask и regex

Inputmask предоставляет два принципиально разных подхода:

Символьная маска

Inputmask("99-99-9999").mask(input);
  • фиксированная структура;
  • каждый символ имеет позицию;
  • используется для дат, телефонов, кодов.

Регулярная маска

Inputmask({
  regex: "\\d{2}-\\d{2}-\\d{4}"
}).mask(input);
  • структура задаётся выражением;
  • отсутствует строгая поэлементная разметка;
  • поведение ближе к pattern в HTML5.

Синтаксис регулярных масок

Регулярное выражение передаётся в виде строки, а не объекта RegExp:

Inputmask({
  regex: "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
}).mask(input);

Важный момент экранирования

Так как выражение передаётся строкой, обратный слэш требует двойного экранирования:

  • \d"\\d"
  • \."\\."

Поведение при вводе

Регулярный режим работает по принципу постепенной проверки:

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

Пример:

Inputmask({
  regex: "[0-9]{0,3}"
}).mask(input);

Здесь допустим ввод до трёх цифр, но каждый промежуточный шаг также проверяется.


Использование для числовых форматов

Регулярные маски часто применяются для числовых ограничений.

Целые числа фиксированной длины

Inputmask({
  regex: "\\d{1,6}"
}).mask(input);

Числа с разделителем

Inputmask({
  regex: "\\d+(\\.\\d{0,2})?"
}).mask(input);

Поддерживается ввод:

  • 10
  • 10.5
  • 10.55

но отклоняются значения с более чем двумя знаками после точки.


Регулярные маски для email

Email-валидация через regex часто применяется в Inputmask как альтернатива HTML pattern:

Inputmask({
  regex: "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}"
}).mask(input);

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


IP-адреса через регулярные выражения

IPv4 можно описать регулярным выражением:

Inputmask({
  regex: "(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}"
}).mask(input);

Такой шаблон учитывает диапазон каждого октета:

  • 0–255;
  • строгое разделение точками;
  • запрет некорректных чисел вроде 999.

Ограничения regex-режима

Несмотря на гибкость, регулярные маски имеют ряд ограничений.

Отсутствие позиционной логики

Невозможно задать поведение вида:

  • «на первом символе только A или B»
  • «на пятом символе зависит от предыдущих»

Регулярное выражение работает глобально.


Сложность частичного ввода

Некоторые сложные выражения:

  • с квантификаторами {n,m}
  • с альтернативами |
  • с жадными квантификаторами

могут вести себя нестабильно при пошаговом вводе, так как regex не всегда однозначно интерпретируется в режиме инкрементальной проверки.


Сравнение с pattern HTML

Регулярный режим Inputmask часто сравнивается с HTML атрибутом pattern, однако поведение отличается.

HTML pattern

  • проверка только при submit или blur;
  • не блокирует ввод;
  • не управляет символами.

Inputmask regex

  • проверка во время ввода;
  • блокировка неподходящих символов;
  • интерактивное ограничение значения.

Использование RegExp-объекта

Некоторые конфигурации допускают передачу RegExp напрямую через настройку mask:

Inputmask({
  mask: new RegExp("\\d+")
}).mask(input);

Однако такой подход используется реже, так как основным механизмом остаётся параметр regex.


Комбинация regex и алиасов

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

Пример числового алиаса с ограничением:

Inputmask("numeric", {
  rightAlign: false,
  regex: "\\d+(\\.\\d{0,2})?"
}).mask(input);

В таких случаях regex выступает дополнительным ограничителем поверх базового поведения алиаса.


Поведение при удалении символов

Регулярный режим пересчитывает соответствие строки при каждом изменении:

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

Производительность сложных выражений

При использовании больших regex-выражений следует учитывать:

  • высокая вложенность снижает скорость проверки;
  • альтернативы с | увеличивают количество путей проверки;
  • квантификаторы с диапазонами {1,100} могут замедлять ввод.

Оптимизация достигается через упрощение выражений и сокращение бэктрекинга.


Практические шаблоны регулярных масок

Коды фиксированного формата

Inputmask({
  regex: "[A-Z]{3}-\\d{4}"
}).mask(input);

Пароли

Inputmask({
  regex: "(?=.*[A-Z])(?=.*\\d)[A-Za-z\\d]{8,}"
}).mask(input);

Временные значения (HH:MM)

Inputmask({
  regex: "([01]\\d|2[0-3]):[0-5]\\d"
}).mask(input);

Частичное соответствие и incremental validation

Ключевая особенность Inputmask в regex-режиме — проверка не только полного совпадения, но и допустимости промежуточного состояния.

Это означает:

  • строка 1 допустима для \\d{2};
  • строка 12 также допустима;
  • строка 123 отклоняется.

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


Использование флага greedy

Хотя greedy чаще относится к символьным маскам, в regex-режиме его влияние косвенно проявляется через квантификаторы:

  • {1,} — потенциально жадное поведение;
  • {0,} — допускает пустое значение.

Контроль жадности влияет на то, насколько рано Inputmask принимает ввод как потенциально валидный.


Интеграция с пользовательскими валидаторами

Регулярные маски часто комбинируются с внешней логикой:

Inputmask({
  regex: "\\d{6}",
  onBeforePaste: function (value) {
    return value.trim();
  }
}).mask(input);

В этом случае regex отвечает за структуру, а обработчики — за предобработку данных.


Поведение при вставке текста

При вставке:

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

Это особенно важно для длинных строк вроде UUID или серийных кодов.


Регулярные выражения и Unicode

Inputmask поддерживает базовую работу с Unicode, однако regex-режим зависит от возможностей JavaScript RegExp:

  • \w не всегда покрывает все Unicode-символы;
  • кириллица требует явного диапазона [А-Яа-я];
  • расширенные Unicode-классы возможны только в современных движках (u flag), который не всегда учитывается в Inputmask.