Регулярные выражения – специальные правила, которые делают процедуру поиска и замены более легкой. С помощью них можно серьёзно улучшить скрипт, применив всего несколько символов. Пользователь с ними сталкивается, когда заполняет форму обратной связи, где сразу проверяется правильность email, телефона и других данных. Для изучения регулярных выражений вам понадобится знание переменных, массивов, циклов, логических операторов, встроенных и пользовательских функций
Для дальнейшей работы нам понадобится функция alert
и replace
. Напоминаем, что это за методы:
1. Первая функция выводит в виде диалогового окна информацию, которая помещается в скобках. Пример использования:
alert("Строка"); // выдаст «Строка»
var elem = "String";
alert(elem); // выдаст «String»
2. Вторая функция ищет указанную строку, после чего меняет её на группу символов. То есть формула выглядит так: "где ищем".replace("что ищем", "на что меняем")
alert( "String".replace("g", "gs") ); // выдаст «Strings»
Важно: строчки надо писать в кавычках (одинарных или двойных), а числа и переменные без них.
Сразу приведём пример, чтобы было понятнее:
alert( "Stringent line".replace(/n/, "@") ); // выдаст «Stri@gent line»
Слеши (/
), в которые заключаем латинскую букву n, именуют ограничителями регулярных выражений. Внутри них некоторые знаки становятся спецсимволами. А сразу после ставятся модификаторы – правила, изменяющие действие регулярного выражения.
Рассмотрим модификатор g
. В приведённом выше коде мы меняли букву n на собачку @, но команда сработала лишь на первом найденном символе. Модификатор g заставляет регулярное выражение находить все совпадения. Пример:
alert( "Stringent line".replace(/n/g, "@") ); // выдаст «Stri@ge@t li@e»
Ставить можно сразу несколько модификаторов. Например, поставим дополнительно i, который отменяет зависимость от регистра:
alert( "Big body".replace(/b/g, "@") ); // выдаст «Big @ody»
alert( "Big body".replace(/b/gi, "@") ); // выдаст «@ig @ody»
Написанные цифры и буквы в большинстве случаев означают сами себя. Но есть и исключения – спецсимволы. Первым из них рассмотрим точку, которая переводится, как «любой символ». Под это понятие попадает не только буква или цифра, но также пробелы, дефисы и прочее:
alert( "wdw w w w1w w&w w-w wddw".replace(/w.w/g, "@") ); // выдаст «@ @ @ @ @ wddw»
Обратите внимание, что пробел тоже является символом. Под регулярное выражение попали все группы (кроме последней). Так как точка означала «любой символ», то она успешно заменила букву d, пробел, цифру 1 и амперсанд. Однако последняя группа – wddw – под правило не попала, так как в ней между w стоит 2 знака, а не один.
Если поставим 2 точки, то регулярное выражение всё равно не захватит все группы символов:
alert( "ww wdw w w w1w w&w w-w wddw".replace(/w..w/g, "@") ); // выдаст «wdw w w w1w w&w w-w @»
Чтобы выражение захватило один, два и более символа, нужно использовать операторы повторения, их ещё называют квантификаторами:
Важно: эти операторы влияют лишь на тот символ, который стоит непосредственно перед ними.
Проще будет понять, если посмотреть на примеры:
alert( "ww wdw wddw wdddw w&w".replace(/wd+w/g, "@") ); // выдаст «ww @ @ @ w&w»
alert( "ww wdw wddw wdddw w&w".replace(/wd*w/g, "@") ); // выдаст «@ @ @ @ w&w»
alert( "ww wdw wddw wdddw w&w".replace(/wd?w/g, "@") ); // выдаст «@ @ wddw wdddw w&w»
В первом примере регулярное выражение искало одно и более совпадений, поэтому буквы «ww» не попали под него. Во втором примере они уже включились в правило. А в третьей строке под регулярное выражение попали лишь первые две группы символов – «ww» и «wdw».
Когда необходимо, чтобы квантификатор влиял сразу на несколько знаков, то можно воспользоваться группированием. Для этого применяют круглые скобки.
alert( "ww wqdw wqdqdw wqddw wqqddw".replace(/w(qd)+w/g, "@") ); // выдаст «ww @ @ wqddw wqqddw»
Как видно из примера, что модификатор повторения (+
) влияет не на каждый символ по отдельности, а на всю строку, как единый объект. Другими словами, требуется точное повторение пары букв «qd», варианты «qdd» или «qqdd» не подходят.
А что если нам требуется найти или заменить точку, знак вопроса или другой спецсимвол? Для этого надо сделать так, чтобы он обозначал сам себя. Это можно сделать с помощью обратного слеша. Приём называется экранирование, а чёрточка ставится непосредственно перед символом. Пример:
alert( "one+two".replace(/e+t/g, "@") ); // выдаст «on@wo»
Однако экранировать можно только спецсимволы, а также буквы (и то не все). С цифрами такой трюк использоваться нельзя, так как они станут карманами (об этом в конце статьи). Но в любом случае обратный слеш желательно использовать лишь по назначению.
К спецсимволам относится $ ^ . * + ? {} [] () |
Обычными символами является @ : , ' '' ; - _ = % # ~ `& ! /
Особенность операторов повтора состоит в том, что они ищут максимально длинную строчку, попадающую под правило. Чтобы стало ясней, сразу напишем пример:
alert( "Stringent line".replace(/s.+n/gi, "@") ); // выдаст «@e»
Регулярное выражение съело максимальное число знаков, закончив на последней n, а не первой. Данное свойство именуется жадностью. Чтобы правило срабатывало лишь до первого символа, нужно после оператора повторения поставить знак вопроса.
Смотрим пример:
alert( "Stringent line".replace(/s.+?n/gi, "@") ); // выдаст «@gent line»
Чтобы убрать жадность у оператора *, нужно написать *?
, тогда он также станет искать лишь до первого совпадения.
А что делать, когда надо указать конкретное число повторов? В этом случае используются фигурные скобки, внутри которых можно указать требуемое количество символов несколькими способами:
Важно: варианта {,5} не существует, вместо этого надо писать {0,5}.
Смотрим пример:
alert( "ww wqdw wqdqdw wqdqdqdw".replace(/w(qd){1,2}w/g, "@") ); // выдаст «ww @ @ wqdqdqdw»
Обратите внимание, что фигурные скобки работают на группу символов в круглых скобках.
Что если нужно выбрать не один-два символа, а целую группу? Например, все буквы или все числа. На помощь приходят специальные обозначения, которые приведены ниже в таблице:
Символ | Значение | Примеры |
s | Пробельный знак | Пробел, табуляция, перевод строки |
S | Не пробел | Всё кроме пробела |
w | Цифра или буква | Цифры и латинские буквы (не кириллица) |
W | Не цифра и не буква | Дефис, амперсанд, точка, запятая, двоеточие, подчёркивание и т.п. |
d | Цифра | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 |
D | Не цифра | Буквы, пробельные символы, другие спецзнаки |
На примерах всё должно быть понятней:
alert( "1 23 456 qwerty @ & # %".replace(/s+/g, "!") ); // выдаст «1!23!456!qwerty!@!&!#!%»
alert( "1 23 456 qwerty @ & # %".replace(/S+/g, "!") ); // выдаст «! ! ! ! ! ! ! !»
alert( "1 23 456 qwerty @ & # %".replace(/w+/g, "!") ); // выдаст «! ! ! ! @ & # %»
alert( "1 23 456 qwerty @ & # %".replace(/W+/g, "!") ); // выдаст «1!23!456!qwerty!»
alert( "1 23 456 qwerty @ & # %".replace(/d+/g, "!") ); // выдаст «! ! ! qwerty @ & # %»
alert( "1 23 456 qwerty @ & # %".replace(/D+/g, "!") ); // выдаст «1!23!456!»
А что если нужно найти перечень конкретных букв? Тогда можно воспользоваться оператором «или», в роли которого могут выступать квадратные скобки или вертикальная черта.
Сразу посмотрим пример:
alert( "wow wqw wdw wqdw wqqddw".replace(/w[qd]w/g, "@") ); // выдаст «wow @ @ wqdw wqqddw»
Как видно, под правило попали лишь те группы символов, где была только буква q или только d, группы с обоими символами под регулярное выражение не подошли.
Также можно сделать отрицание «всё кроме … или …» с помощью шляпки ^:
alert( "ow qw dw 1w".replace(/[^qd]w/g, "@") ); // выдаст «@ qw dw @»
С помощью дефиса можно указывать группы символов:
Их можно группировать:
Приведём пример для ясности:
alert( "ow qw dw 1w".replace(/[a-z]w/g, "@") ); // выдаст «@ @ @ 1w»
А что если нужно включить в группу дефис или шляпку? Тогда нужно поставить их туда, где они не будут являться спецсимволами. Шляпку пишут в конце, а дефис – в начале или в конце. Также можно воспользоваться экранированием. Ещё спецсимволом внутри [ ] являются сами квадратные скобки, поэтому их тоже надо экранировать.
Кроме того, существует другой оператор «или» – прямая вертикальная черта. Вот наглядный пример:
alert( "ow qw dw 1w".replace(/q|d/g, "@") ); // выдаст «ow @w @w 1w»
Теперь попробуем сделать так, чтобы регулярное выражение заменяло группы «qw» или «dw»:
alert( "ow qw dw 1w".replace(/q|dw/g, "@") ); // выдаст «ow @w @ 1w»
Вместо того чтобы заменить группы «qw» или «dw», регулярное выражение сработало на «q» и «dw». То есть вертикальная черта ставит выбор между всеми символами, которые стоят перед и после неё.
Чтобы добиться требуемого результата, нужно сгруппировать буквы. Сделать это можно с помощью круглых скобок. Вот так:
alert( "ow qw dw 1w".replace(/(q|d)w/g, "@") ); // выдаст «ow @ @ 1w»
Важным отличием оператора | от квадратных скобок является то, что в нём допускается применение спецзнаков повторения *?+ к отдельным символам. Что невозможно внутри [ ], так как в нём данные квантификаторы являются обычными символами.
Первое и главное – кириллица не включена в w, поэтому требуется писать [а-яА-Я]. Второй и тоже важный момент – к указанной группе не причисляется буква ё, так что лучше писать [а-яА-ЯЁё].
Работает это вот так:
alert( "ас ад ау ах а1 аё".replace(/а[б-яё]/g, "@") ); // выдаст «@ @ @ @ а1 @»
С помощью обозначений начала ^ и конца строки $ можно указывать, что символ должен стоят первым или последним в строчке.
Примеры:
alert( "ас ад ау ах а1 аё".replace(/^а[б-яё]/g, "@") ); // выдаст «@ ад ау ах а1 аё»
alert( "ас ад ау ах а1 аё".replace(/а[б-яё]$/g, "@") ); // выдаст «ас ад ау ах а1 @»
Если в начале регулярного выражения поставить ^, а в конце - $, то правило будет проверять на соответствие всю строчку целиком.
Обратный слеш использует не только в регулярных выражениях, а вообще применяется в JavaScript повсеместно для экранирования спецсимволов, чтобы они становились обычными символами.
В частности используется для того, чтобы кавычки в строчном элементе обозначали сами себя:
var str = "это \" кавычки";
Чтобы поставить обратный слеш, как обычный символ, его нужно экранировать. То есть писать 2 раза подряд:
var str = "это \\ обратный слеш";
Об этом правиле надо помнить, когда вы используете регулярные выражения
Круглые скобки используются не только для группировки, но также для создания «карманов» – специального правила, которое сохраняет часть того, что мы ищем по регулярному выражению. После чего можно достать содержимое кармана с помощью знака доллара и цифры, которая означает его порядковый номер: $1, $2 …
Чтобы было понятнее, лучше привести пример:
alert( "ow qw dw 1w".replace(/(q|d)w/g, "w$1") ); // выдаст «ow wq wd 1w»
С помощью карманов можно делать интересный фокус – менять содержимое строки местами:
alert( "w&s ww&ss".replace(/([a-z]+)&([a-z]+)/g, "$2@$1") ); // выдаст «s@w ss@ww»
В данном выражении то, что стоит перед амперсандом, кладётся в первый карман, а то, что стоит после &, попадает во второй. После чего первый и второй карманы меняются местами.
А что если нужно сгруппировать символы, но не класть их в карман? В такой ситуации после открывающей скобки ставится знак вопроса и двоеточие:
alert( "w&s ww&ss".replace(/(?:[a-z]+)&([a-z]+)/g, "@$1") ); // выдаст «@s @ss»
В первые скобки попадают буквы «w» и «ww», но они не попадают в карман, поэтому в $1 лежат символы «s» и «ss».
Чаще всего их применяют для проверки сложности пароля (чтобы были буквы и цифры), правильности ввода email, номера телефона и других данных при заполнении формы обратной связи. Также они используются для проверки расширения загружаемых файлов, доменных зон. Применение регулярных выражений очень широко и ограничивается лишь фантазией.