Регулярки одновременно очень странные и крайне полезные. Их синтаксис загадочен, а программный интерфейс в JavaScript для них неуклюж. Но это мощный инструмент для исследования и обработки строк. Разобравшись с ними, вы станете более эффективным программистом.
Создаём регулярное выражение
Регулярка – тип объекта. Её можно создать, вызвав конструктор RegExp
, или написав нужный шаблон, окружённый слэшами.
var re1 = new RegExp("abc");
var re2 = /abc/;
Оба этих регулярных выражения представляют один шаблон: символ “a”, за которым следует символ “b”, за которым следует символ “c”.
Если вы используете конструктор RegExp
, тогда шаблон записывается как обычная строка, поэтому действуют все правила относительно обратных слэшей.
Вторая запись, где шаблон находится между слэшами, обрабатывает обратные слэши по-другому. Во-первых, так как шаблон заканчивается прямым слэшем, то нужно ставить обратный слэш перед прямым слэшем, который мы хотим включить в наш шаблон. Кроме того, обратные слэши, не являющиеся частью специальных символов типа \n
, будут сохранены (а не проигнорированы, как в строках), и изменят смысл шаблона. У некоторых символов, таких, как знак вопроса или плюс, есть особое значение в регулярках, и если вам нужно найти такой символ, его также надо предварять обратным слэшем.
var eighteenPlus = /eighteen\+/;
Чтобы знать, какие символы надо предварять слэшем, вам надо выучить список всех специальных символов в регулярках. Пока это нереально, поэтому в случае сомнений просто ставьте обратный слэш перед любым символом, не являющимся буквой, числом или пробелом.
Проверяем на совпадения
У регулярок есть несколько методов. Простейший – test
. Если передать ему строку, он вернёт булевское значение, сообщая, содержит ли строка вхождение заданного шаблона.
console.log(/abc/.test("abcde"));
// → true
console.log(/abc/.test("abxde"));
// → false
Регулярка, состоящая только из неспециальных символов, просто представляет собой последовательность этих символов. Если abc
есть где-то в строке, которую мы проверяем (не только в начале), test
вернёт true
.
Ищем набор символов
Выяснить, содержит ли строка abc
, можно было бы и при помощи indexOf
. Регулярки позволяют пройти дальше и составлять более сложные шаблоны.
Допустим, нам надо найти любой номер. Когда мы в регулярке помещаем набор символов в квадратные скобки, это означает, что эта часть выражения совпадает с любым из символов в скобках.
Оба выражения находятся в строчках, содержащих цифру.
console.log(/[0123456789]/.test("in 1992"));
// → true
console.log(/[0-9]/.test("in 1992"));
// → true
В квадратных скобках тире между двумя символами используется для задания диапазона символов, где последовательность задаётся кодировкой Unicode. Символы от 0 до 9 находятся там просто подряд (коды с 48 до 57), поэтому [0-9]
захватывает их все и совпадает с любой цифрой.
У нескольких групп символов есть свои встроенные сокращения:
\d
– любая цифра
\w
– алфавитно-цифровой символ
\s
– пробельный символ (пробел, табуляция, перевод строки, и т. п.)
\D
– не цифра
\W
– не алфавитно-цифровой символ
\S
– не пробельный символ
.
– любой символ, кроме перевода строки
Таким образом можно задать формат даты и времени вроде 30-01-2003 15:20 следующим выражением:
var dateTime = /\d\d-\d\d-\d\d\d\d \d\d:\d\d/;
console.log(dateTime.test("30-01-2003 15:20"));
// → true
console.log(dateTime.test("30-jan-2003 15:20"));
// → false
Выглядит ужасно, не так ли? Слишком много обратных слэшей, которые затрудняют понимание шаблона. Позже мы слегка улучшим его.
Обратные слэши можно использовать и в квадратных скобках. Например, [\d.]
означает любую цифру или точку. Заметьте, что точка внутри квадратных скобок теряет своё особое значение и превращается просто в точку. То же касается и других специальных символов, типа +
.
Инвертировать набор символов – то есть, сказать, что вам надо найти любой символ, кроме тех, что есть в наборе – можно, поставив знак ^
сразу после открывающей квадратной скобки.
var notBinary = /[^01]/;
console.log(notBinary.test("1100100010100110"));
// → false
console.log(notBinary.test("1100100010200110"));
// → true
Повторяем части шаблона
Мы знаем, как найти одну цифру. А если нам надо найти число целиком – последовательность из одной или более цифр?