Регулярні вирази – потужний засіб пошуку та заміни тексту в рядках.
В JavaScript регулярні вирази реалізовані окремим об’єктом RegExp та інтегровані у методи рядків.
Регулярні вирази
Регулярний вираз (він же “регексп”, “регулярка” або просто “рег”), складається з шаблону (також кажуть “патерн”) і необов’язкових прапорців.
Існує два синтаксиси для створення регулярного виразу.
“Довгий” синтаксис:
regexp =
new
RegExp
(
"шаблон"
,
"прапорці"
)
;
Та “короткий” синтаксис, в якому використовуються слеши "/"
:
regexp =
/
шаблон
/
;
// без прапорців
regexp =
/
шаблон
/
gmi
;
// з прапорцями g,m та i (будуть описані далі)
Слеши /.../
говорять JavaScript про те, що це регулярний вираз. Вони відіграють таку саму роль, як і лапки для позначення рядків.
Регулярний вираз regexp
в обох випадках є об’єктом вбудованого класу RegExp
.
Основна різниця між цими двома синтаксами полягає в тому, що слеши /.../
не допускають жодних вставок змінних (на зразок тих, що прописуються через ${...}
). Вони повністю статичні.
Слеши використовуються, коли ми на момент написання коду точно знаємо, яким буде регулярний вираз – і це більшість ситуацій. А new RegExp
– коли ми хочемо створити регулярний вираз “на льоту” з динамічно згенерованого рядка, наприклад:
let
tag =
prompt
(
"Який тег ви хочете знайти?"
,
"h2"
)
;
let
regexp =
new
RegExp
(
`
<
${
tag}
>
`
)
;
// те саме, що /<h2>/ при відповіді "h2" на запит вище
Прапорці
Регулярні вирази можуть мати прапорці, які впливають на пошук.
У JavaScript їх всього шість:
i
- З цим прапорцем пошук не залежить від регістру: немає різниці між
A
таa
(див. приклад нижче). g
- З цим прапорцем пошук шукає всі збіги, без нього – лише перший.
m
- Багаторядковий режим (розглядається в розділі Багаторядковий режим якорів ^ $, прапорець "m").
s
- Вмикає режим “dotall”, при якому крапка
.
може відповідати символу нового рядка\n
(розглядається у розділі Символьні класи). u
- Вмикає повну підтримку Юнікоду. Цей прапорець дозволяє коректну обробку сурогатних пар (докладніше про це у розділі Юнікод: прапорець "u" та клас \p{...}).
y
- Режим пошуку на конкретній позиції в тексті (описаний у розділі Липкий прапорець "y", пошук на заданій позиції)
Тут і далі в тексті використовується наступна схема кольорів:
- регулярний вираз –
червоний
- рядок (там, де відбувається пошук) –
синій
- результат –
зелений
Пошук: 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
Далі в цьому розділі ми вивчатимемо регулярні вирази, побачимо ще багато прикладів їх використання, а також познайомимося з іншими методами.
Повна інформація про різні методи наведена в розділі Методи регулярних виразів та рядків.
Підсумки
- Регулярний вираз складається з шаблону і необов’язкових прапорців:
g
,i
,m
,u
,s
,y
. - Без прапорців та спеціальних символів, які ми вивчимо пізніше, пошук за регулярним виразом аналогічний пошуку підрядка.
- Метод
str.match(regexp)
шукає збіги: всі, якщо є прапорецьg
, інакше тільки перший. - Метод
str.replace(regexp, replacement)
замінює збіги зregexp
наreplacement
: всі, якщо у регулярного виразу є прапорецьg
, інакше тільки перший. - Метод
regexp.test(str)
повертаєtrue
, якщо є хоч один збіг, інакшеfalse
.
Коментарі
<code>
, для кількох рядків – обгорніть їх тегом<pre>
, для понад 10 рядків – використовуйте пісочницю (plnkr, jsbin, codepen…)