Разрешенные и запрещенные символы

Библиотека Validator.js предоставляет набор инструментов для проверки строковых данных, где одной из ключевых задач является контроль допустимых и запрещённых символов. Подход основан на комбинации предопределённых валидаторов, регулярных выражений и пользовательских правил, позволяющих гибко формировать политики ввода.


Модель проверки символов

Проверка символов в Validator.js строится вокруг идеи нормализации входной строки и последующего применения правил соответствия. Входные данные рассматриваются как последовательность символов, к которой применяются ограничения:

  • принадлежность допустимому набору;
  • отсутствие запрещённых символов;
  • соответствие шаблону;
  • соблюдение локализованных правил (Unicode, алфавиты разных языков).

Основной принцип — декларативное описание правил, а не ручная постсимвольная обработка.


Белые списки символов (whitelist)

Белый список определяет строго разрешённый набор символов. Всё, что не входит в него, считается недопустимым.

В Validator.js исторически использовалась функция whitelist, позволяющая ограничить строку заданным набором символов:

const validator = require('validator');

validator.whitelist('user_123', 'abcdefghijklmnopqrstuvwxyz0123456789_');

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

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

Белый список применяется там, где требуется строгий контроль формата: идентификаторы, системные ключи, технические токены.


Чёрные списки символов (blacklist)

Чёрный список работает по обратному принципу — запрещает конкретные символы, оставляя всё остальное допустимым.

validator.blacklist('user<script>', '<>');

Характерные особенности:

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

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


Регулярные выражения как основа фильтрации

Наиболее универсальный механизм контроля символов в Validator.js — использование регулярных выражений через matches.

validator.matches('User_123', /^[a-zA-Z0-9_]+$/);

Регулярные выражения позволяют:

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

Примеры шаблонов:

// Только латиница
/^[a-zA-Z]+$/

// Латиница и цифры
/^[a-zA-Z0-9]+$/

// Разрешены буквы, цифры, подчёркивание и дефис
/^[a-zA-Z0-9_-]+$/

Регулярные выражения фактически заменяют белые и чёрные списки, обеспечивая более точную настройку правил.


Проверка алфавитно-цифровых наборов

Validator.js включает специализированные функции для базовых категорий символов:

  • isAlpha — только буквенные символы;
  • isNumeric — только цифры;
  • isAlphanumeric — комбинация букв и цифр.
validator.isAlphanumeric('User123');

Особенности поведения:

  • по умолчанию учитывается только ASCII-диапазон;
  • поведение может изменяться с учётом локали;
  • символы пробелов и пунктуации исключаются.

Такие функции используются как быстрый фильтр перед более сложной валидацией.


Обработка Unicode и локалей

Современные версии Validator.js учитывают необходимость работы с Unicode-символами. Это особенно важно для многоязычных систем.

validator.isAlpha('тест', 'ru-RU');

Локализованная проверка влияет на:

  • допустимые алфавиты;
  • диапазоны символов Unicode;
  • интерпретацию диакритических знаков.

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


Комбинированные правила

Реальные сценарии редко ограничиваются одной проверкой. Validator.js позволяет строить цепочки условий на уровне приложения:

const isValidUsername =
  validator.isLength(username, { min: 3, max: 20 }) &&
  validator.matches(username, /^[a-zA-Z0-9_]+$/);

Комбинации обычно включают:

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

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


Практические сценарии использования

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

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

/^[a-zA-Z0-9_.-]+$/

Типичные требования:

  • отсутствие пробелов;
  • запрет спецсимволов вроде <, >, &;
  • разрешение ограниченного набора разделителей.

Пароли

Контроль символов в паролях обычно более гибкий:

validator.matches(password, /^[\x20-\x7E]+$/);

Особенности:

  • допускаются печатные ASCII-символы;
  • запрещаются управляющие символы;
  • часто добавляется проверка сложности отдельно.

Теги и метки

validator.matches(tag, /^[a-z0-9-]+$/);

Характерные ограничения:

  • только строчные буквы;
  • цифры;
  • дефис как разделитель слов.

Ошибки проектирования фильтрации символов

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

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

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


Производительность и ограничения

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

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

Белые списки через whitelist и простые проверки алфавита работают быстрее, но менее гибки по сравнению с регулярными выражениями.

Баланс между читаемостью правил и производительностью становится ключевым фактором при проектировании систем валидации символов.