Регулярні вирази – потужний засіб пошуку та заміни тексту в рядках.
В 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( "Ми будемо, ми будемо".replace(/ми/i, "Я") ); // Я будемо, ми будемо
// з прапором g
alert( "Ми будемо, ми будемо".replace(/ми/ig, "Я") ); // Я будемо, Я будемо
У рядку заміни 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
.