Наборы и диапазоны в регулярных выражениях JavaScript
Наборы и диапазоны в регулярных выражениях JavaScript — мощный инструмент для обработки и проверки текста. Узнайте, как использовать [...] и [^...].
Регулярные выражения (regex) в JavaScript — это мощный инструмент для обработки и манипуляции текстом. Набор символов (или символьный класс) позволяет указать «совпасть с любым из этих символов» в заданной позиции строки — строительный блок, к которому постоянно обращаются при валидации ввода, разборе текста или очистке данных.
В этом руководстве рассматриваются наборы [...], диапазоны вида [a-z0-9], отрицание [^...], экранирование специальных символов внутри набора, а также сочетание наборов с сокращёнными классами \w и \d. Все примеры можно запустить, чтобы убедиться в результате самостоятельно.
Введение в наборы в регулярных выражениях
Набор в регулярном выражении задаёт группу символов, любой из которых может совпасть в данной позиции строки поиска. Наборы записываются в квадратных скобках []. Принципиально важно: набор совпадает ровно с одним символом — [abc] совпадает с одной a, b или c, но не со строкой "abc".
Базовые наборы
Например, набор [abc] совпадёт с любым отдельным символом — a, b или c. При использовании флага g метод match() возвращает все найденные такие символы:
Отрицательные наборы
Чтобы создать отрицательный набор, совпадающий с любым символом, которого нет в списке, поставьте каретку ^ сразу после открывающей скобки. Например, [^abc] совпадает с любым символом, кроме a, b и c. Каретка имеет это специальное значение только в первой позиции; в любом другом месте она является обычным символом.
Понимание диапазонов
Внутри набора можно записать диапазон через дефис — начало-конец — вместо перечисления каждого символа. Диапазон совпадает с любым символом, кодовая точка которого находится между двумя граничными значениями включительно. Это делает шаблоны короткими и понятными.
Числовые диапазоны
Например, [0-9] представляет любую цифру от 0 до 9. Добавление + позволяет совпадать с одной или несколькими цифрами подряд, поэтому последовательные цифры группируются в одно совпадение:
Алфавитные диапазоны
Аналогично [a-z] совпадает с любой строчной буквой, а [A-Z] — с любой прописной. В одном наборе можно указать несколько диапазонов — [A-Za-z0-9] охватывает буквы и цифры — для совпадения с несколькими видами символов одновременно:
Распространённый практический пример — базовая проверка идентификатора, где первый символ должен быть буквой, а остальные могут быть буквами, цифрами или знаками подчёркивания:
Расширенное использование наборов и диапазонов
Внутрь набора можно добавлять сокращённые классы рядом с обычными символами и диапазонами. Сокращения работают внутри [...] так же, как и снаружи:
\d— цифра, эквивалент[0-9]\w— «словесный» символ:[A-Za-z0-9_]\s— пробельный символ (пробел, табуляция, перевод строки, …)
Таким образом [\d.] означает «цифра или точка», а [\w-] — «словесный символ или дефис». Полный список и отрицательные формы в верхнем регистре (\D, \W, \S) см. в разделе Символьные классы.
Пример: объединение словесных символов и специальных знаков
Вот практический случай: оставить словесные символы и один конкретный знак пунктуации, игнорируя всё остальное.
Здесь \w охватывает все буквы, цифры и знак подчёркивания. Добавление ! в набор также позволяет совпасть с восклицательным знаком, который \w не включает. Это удобно, когда нужно допустить несколько конкретных символов, не открывая совпадение для всей пунктуации.
Поддержка Unicode и многоязычность
Диапазоны вида [a-z] охватывают только ASCII-буквы — они пропускают символы с диакритическими знаками и не-латинские символы. Для совпадения с буквами любого языка используйте экранирования свойств Unicode (ECMAScript 2018+) вместе с флагом u. Например, \p{L} совпадает с любой буквой любого алфавита:
Флаг u обязателен для работы \p{...}. Подробнее в разделе Флаг unicode "u" и класс \p{...} и обзоре Шаблоны и флаги.
Исключение диапазонов в регулярных выражениях
Отрицание работает и с диапазонами. [^0-9] совпадает с любым нецифровым символом, а после каретки можно сочетать диапазоны и отдельные символы. Частая задача — отфильтровать или найти всё, что не входит в допустимую группу — здесь каждый символ, не являющийся гласной (флаг i делает поиск нечувствительным к регистру):
Пример исключения диапазонов
Это регулярное выражение найдёт все негласные символы, включая знаки пунктуации и пробелы. Мощный способ отфильтровать нежелательные символы из строки.
Экранирование специальных символов в наборах
Внутри набора специальных символов значительно меньше, чем снаружи. Нужно беспокоиться лишь о четырёх: закрывающей скобке ], обратном слэше \, каретке ^ (специальная только в начале) и дефисе - (специальный только между двумя символами). Любой из них можно экранировать обратным слэшем для буквального использования.
Полезное сокращение: дефис воспринимается буквально, если он стоит первым или последним символом в наборе, поэтому [-+] и [a-z-] не требуют экранирования. Аналогично символы, специальные вне набора — такие как ., *, +, (, ) — теряют своё значение внутри него и совпадают буквально, поэтому [.+] просто совпадает с точкой или плюсом.
Пример экранирования специальных символов
Здесь скобки экранированы, поэтому они воспринимаются как обычные символы, а не как открывающие и закрывающие набор. Следующий пример показывает правило «дефис как буква» и правило «точка теряет силу» вместе:
Заключение
Освоение наборов и диапазонов в регулярных выражениях JavaScript не только расширяет возможности работы со строками, но и позволяет писать более чистый и эффективный код. Они особенно мощны для разбора текста, валидации ввода и обработки данных в веб-разработке.