Регулярные выражения – мощное средство поиска и замены в строке.
В JavaScript регулярные выражения реализованы отдельным объектом RegExp и интегрированы в методы строк.
Регулярные выражения
Регулярное выражение (оно же «регэксп», «регулярка» или просто «рег»), состоит из шаблона (также говорят «паттерн») и необязательных флагов.
Существует два синтаксиса для создания регулярного выражения.
«Длинный» синтаксис:
regexp =
new
RegExp
(
"шаблон"
,
"флаги"
)
;
…И короткий синтаксис, использующий слеши "/"
:
regexp =
/
шаблон
/
;
// без флагов
regexp =
/
шаблон
/
gmi
;
// с флагами gmi (будут описаны далее)
Слеши /.../
говорят JavaScript о том, что это регулярное выражение. Они играют здесь ту же роль, что и кавычки для обозначения строк.
Регулярное выражение regexp
в обоих случаях является объектом встроенного класса RegExp
.
Основная разница между этими двумя способами создания заключается в том, что слеши /.../
не допускают никаких вставок переменных (наподобие возможных в строках через ${...}
). Они полностью статичны.
Слеши используются, когда мы на момент написания кода точно знаем, каким будет регулярное выражение – и это большинство ситуаций. А new RegExp
– когда мы хотим создать регулярное выражение «на лету» из динамически сгенерированной строки, например:
let
tag =
prompt
(
"Какой тег вы хотите найти?"
,
"h2"
)
;
let
regexp =
new
RegExp
(
`
<
${
tag}
>
`
)
;
// то же, что /<h2>/ при ответе "h2" на prompt выше
Флаги
Регулярные выражения могут иметь флаги, которые влияют на поиск или предоставляют дополнительную информацию.
В JavaScript их всего семь:
i
- С этим флагом поиск не зависит от регистра: нет разницы между
A
иa
(см. пример ниже). g
- С этим флагом поиск ищет все совпадения, без него – только первое.
m
- Многострочный режим (рассматривается в главе Многострочный режим якорей ^ $, флаг "m").
s
- Включает режим «dotall», при котором точка
.
может соответствовать символу перевода строки\n
(рассматривается в главе Символьные классы). u
- Включает полную поддержку Юникода. Флаг разрешает корректную обработку суррогатных пар (подробнее об этом в главе Юникод: флаг "u" и класс \p{...}).
y
- Режим поиска на конкретной позиции в тексте (описан в главе Поиск на заданной позиции, флаг "y").
d
- С этим флагом результат регулярного выражения помещается в массив, который содержит дополнительную информацию о регулярном выражении, например индексы начала и конца подстрок. Этот флаг не меняет поведение регулярного выражения, а лишь предоставляет дополнительную информацию.
Здесь и далее в тексте используется следующая цветовая схема:
- регулярное выражение –
красный
- строка (там где происходит поиск) –
синий
- результат –
зелёный
Поиск: str.match
Как уже говорилось, использование регулярных выражений интегрировано в методы строк.
Метод str.match(regexp)
для строки str
возвращает совпадения с регулярным выражением regexp
.
У него есть три режима работы:
-
Если у регулярного выражения есть флаг
g
, то он возвращает массив всех совпадений:let
str=
"Любо, братцы, любо!"
;
alert
(
str.
match
(
/
любо
/
gi
)
)
;
// Любо,любо (массив из 2х подстрок-совпадений)
Обратите внимание: найдены и
Любо
илюбо
, благодаря флагуi
, который делает регулярное выражение регистронезависимым. -
Если такого флага нет, то возвращает только первое совпадение в виде массива, в котором по индексу
0
находится совпадение, и есть свойства с дополнительной информацией о нём:let
str=
"Любо, братцы, любо!"
;
let
result=
str.
match
(
/
любо
/
i
)
;
// без флага g
alert
(
result[
0
]
)
;
// Любо (первое совпадение)
alert
(
result.
length)
;
// 1
// Дополнительная информация:
alert
(
result.
index)
;
// 0 (позиция совпадения)
alert
(
result.
input)
;
// Любо, братцы, любо! (исходная строка)
В этом массиве могут быть и другие индексы, кроме
0
, если часть регулярного выражения выделена в скобки. Мы разберём это в главе Скобочные группы. -
И, наконец, если совпадений нет, то, вне зависимости от наличия флага
g
, возвращаетсяnull
.Это очень важный нюанс. При отсутствии совпадений возвращается не пустой массив, а именно
null
. Если об этом забыть, можно легко допустить ошибку, например:let
matches=
"JavaScript"
.
match
(
/
HTML
/
)
;
// = null
if
(
!
matches.
length)
{
// Ошибка: у null нет свойства length
alert
(
"Ошибка в строке выше"
)
;
}
Если хочется, чтобы результатом всегда был массив, можно написать так:
let
matches=
"JavaScript"
.
match
(
/
HTML
/
)
||
[
]
;
if
(
!
matches.
length)
{
alert
(
"Совпадений нет"
)
;
// теперь работает
}
Замена: str.replace
Метод str.replace(regexp, replacement)
заменяет совпадения с regexp
в строке str
на replacement
(все, если есть флаг g
, иначе только первое).
Например:
// без флага g
alert
(
"We will, we will"
.
replace
(
/
we
/
i
,
"I"
)
)
;
// I will, we will
// с флагом g
alert
(
"We will, we will"
.
replace
(
/
we
/
ig
,
"I"
)
)
;
// I will, I will
В строке замены replacement
мы можем использовать специальные комбинации символов для вставки фрагментов совпадения:
Спецсимволы | Действие в строке замены |
---|---|
$& |
вставляет всё найденное совпадение |
$` |
вставляет часть строки до совпадения |
$' |
вставляет часть строки после совпадения |
$n |
если n это 1-2 значное число, вставляет содержимое n-й скобочной группы регулярного выражения, больше об этом в главе Скобочные группы |
$<name> |
вставляет содержимое скобочной группы с именем name , также изучим в главе Скобочные группы |
$$ |
вставляет символ "$" |
Пример с $&
:
alert
(
"Люблю HTML"
.
replace
(
/
HTML
/
,
"$& и JavaScript"
)
)
;
// Люблю HTML и JavaScript
Проверка: regexp.test
Метод regexp.test(str)
проверяет, есть ли хоть одно совпадение, если да, то возвращает true
, иначе false
.
let
str =
"Я ЛюБлЮ JavaScript"
;
let
regexp =
/
люблю
/
i
;
alert
(
regexp.
test
(
str)
)
;
// true
Далее в этом разделе мы будем изучать регулярные выражения, увидим ещё много примеров их использования, а также познакомимся с другими методами.
Полная информация о различных методах дана в главе Методы RegExp и String.
Итого
- Регулярное выражение состоит из шаблона и необязательных флагов:
g
,i
,m
,u
,s
,y
,d
. - Без флагов и специальных символов, которые мы изучим позже, поиск по регулярному выражению аналогичен поиску подстроки.
- Метод
str.match(regexp)
ищет совпадения: все, если есть флагg
, иначе только первое. - Метод
str.replace(regexp, replacement)
заменяет совпадения сregexp
наreplacement
: все, если у регулярного выражения есть флагg
, иначе только первое. - Метод
regexp.test(str)
возвращаетtrue
, если есть хоть одно совпадение, иначеfalse
.
Комментарии
<code>
, для нескольких строк кода — тег<pre>
, если больше 10 строк — ссылку на песочницу (plnkr, JSBin, codepen…)