Пошук уроків, статей та іншого контенту
Дізнаєтеся, як задавати кількість повторень за допомогою жадібних і ледачих квантифікаторів.
Квантифікатори в регулярних виразах визначають, скільки разів може повторюватися символ, група або клас символів.
Наприклад:
const pattern = /a+/;Квантифікатор + означає: символ a має повторитися один або більше разів.
console.log("a".match(pattern)); // [ 'a' ]
console.log("aaa".match(pattern)); // [ 'aaa' ]
console.log("bbb".match(pattern)); // nullКвантифікатор застосовується до елемента, який стоїть безпосередньо перед ним:
/ab+/ // символ b може повторюватися
/(ab)+/ // група ab може повторюватися
/[0-9]+/ // клас цифр може повторюватися* — нуль або більше повтореньКвантифікатор * означає: елемент може повторитися нуль або більше разів.
const pattern = /ba*/;
console.log("b".match(pattern)); // [ 'b' ]
console.log("ba".match(pattern)); // [ 'ba' ]
console.log("baaa".match(pattern)); // [ 'baaa' ]
console.log("c".match(pattern)); // nullУ цьому прикладі a* дозволяє:
не мати символу a;
мати один символ a;
мати багато символів a.
Тому шаблон /ba*/ знаходить b, навіть якщо після нього немає a.
+ — одне або більше повтореньКвантифікатор + означає: елемент має повторитися щонайменше один раз.
const pattern = /ba+/;
console.log("b".match(pattern)); // null
console.log("ba".match(pattern)); // [ 'ba' ]
console.log("baaa".match(pattern)); // [ 'baaa' ]Різниця між * і +:
/ba*/ // b, ba, baa, baaa
/ba+/ // ba, baa, baaa? — нуль або один разКвантифікатор ? означає: елемент є необов’язковим і може з’явитися не більше одного разу.
const pattern = /colou?r/;
console.log("color".match(pattern)); // [ 'color' ]
console.log("colour".match(pattern)); // [ 'colour' ]
console.log("colouur".match(pattern)); // nullУ шаблоні /colou?r/ символ u може бути:
відсутнім: color;
присутнім один раз: colour.
Символ ? також часто використовується після групи:
const pattern = /https?:\/\//;
console.log("http://example.com".match(pattern)); // [ 'http://' ]
console.log("https://example.com".match(pattern)); // [ 'https://' ]Тут s? означає, що літера s є необов’язковою.
{n} — рівно n повтореньФорма {n} вимагає рівно задану кількість повторень.
const pattern = /\d{4}/;
console.log("2025".match(pattern)); // [ '2025' ]
console.log("123".match(pattern)); // nullШаблон /\d{4}/ знаходить чотири цифри підряд.
За замовчуванням збіг може бути частиною довшого рядка:
console.log("Рік: 2025".match(/\d{4}/)); // [ '2025' ]
console.log("12345".match(/\d{4}/)); // [ '1234' ]Щоб перевірити, що весь рядок складається рівно з чотирьох цифр, використовуйте якорі:
const pattern = /^\d{4}$/;
console.log(pattern.test("2025")); // true
console.log(pattern.test("12345")); // false
console.log(pattern.test("Рік: 2025")); // false{n,} — щонайменше n повтореньФорма {n,} означає: елемент має повторитися не менше ніж n разів.
const pattern = /\d{2,}/;
console.log("12".match(pattern)); // [ '12' ]
console.log("123456".match(pattern)); // [ '123456' ]
console.log("7".match(pattern)); // nullПробіл після коми ставити не можна:
/\d{2,}/ // правильно
/\d{2, }/ // це вже інший шаблон і зазвичай не те, що потрібно{n,m} — від n до m повтореньФорма {n,m} задає мінімальну та максимальну кількість повторень.
const pattern = /\d{2,4}/;
console.log("12".match(pattern)); // [ '12' ]
console.log("123".match(pattern)); // [ '123' ]
console.log("1234".match(pattern)); // [ '1234' ]
console.log("1".match(pattern)); // nullДля рядка "12345" результатом буде перші чотири цифри:
console.log("12345".match(/\d{2,4}/)); // [ '1234' ]Квантифікатор може застосовуватися не лише до одного символу.
Дужки об’єднують кілька символів у групу:
const pattern = /(ha){2,3}/;
console.log("haha".match(pattern)); // [ 'haha' ]
console.log("hahaha".match(pattern)); // [ 'hahaha' ]
console.log("ha".match(pattern)); // nullГрупа (ha) повторюється від двох до трьох разів.
Без дужок квантифікатор застосувався б лише до останнього символу:
/ha{2}/ // h + два символи a: "haa"
/(ha){2}/ // дві групи "ha": "haha"const pattern = /[a-z]{3}/;
console.log("cat".match(pattern)); // [ 'cat' ]
console.log("dog".match(pattern)); // [ 'dog' ]
console.log("a1b".match(pattern)); // nullШаблон /[a-z]{3}/ знаходить три малі латинські літери підряд.
Приклад перевірки простого коду:
const codePattern = /^[A-Z]{2}-\d{4}$/;
console.log(codePattern.test("AB-1234")); // true
console.log(codePattern.test("A-1234")); // false
console.log(codePattern.test("ab-1234")); // falseЗа замовчуванням квантифікатори є жадібними. Це означає, що вони намагаються захопити якомога більше символів, але так, щоб увесь регулярний вираз залишався успішним.
До жадібних належать:
*
+
?
{n}
{n,}
{n,m}Розглянемо приклад із HTML-подібним текстом:
const text = "<b>Перший</b> і <b>другий</b>";
const pattern = /<b>.*<\/b>/;
console.log(text.match(pattern));
// [ '<b>Перший</b> і <b>другий</b>' ]Квантифікатор .* є жадібним. Він захоплює текст від першого <b> до останнього можливого </b>.
Це може бути небажаним результатом, якщо потрібно знайти кожен окремий фрагмент.
Ледачий квантифікатор намагається захопити якомога менше символів, але так, щоб регулярний вираз залишався успішним.
Щоб зробити квантифікатор ледачим, після нього додають ?:
*? нуль або більше, ледаче
+? один або більше, ледаче
?? нуль або один, ледаче
{n,m}? від n до m, ледаче
{n,}? щонайменше n, ледаче*?const text = "<b>Перший</b> і <b>другий</b>";
const pattern = /<b>.*?<\/b>/g;
console.log(text.match(pattern));
// [ '<b>Перший</b>', '<b>другий</b>' ]Тепер .*? зупиняється на першому можливому </b>. Прапорець g дозволяє знайти всі збіги, а не лише перший.
Порівняння:
const text = "<b>Перший</b> і <b>другий</b>";
console.log(text.match(/<b>.*<\/b>/));
// [ '<b>Перший</b> і <b>другий</b>' ]
console.log(text.match(/<b>.*?<\/b>/g));
// [ '<b>Перший</b>', '<b>другий</b>' ]Розглянемо рядок із лапками:
const text = 'Імена: "Анна", "Олег", "Марія"';
console.log(text.match(/".*"/));
// [ '"Анна", "Олег", "Марія"' ]
console.log(text.match(/".*?"/g));
// [ '"Анна"', '"Олег"', '"Марія"' ]Жадібний .* охоплює все між першою та останньою лапкою.
Ледачий .*? зупиняється на першій можливій лапці, а прапорець g дає змогу знайти всі окремі значення.
Ледачі квантифікатори корисні, але часто можна написати точніший шаблон.
Наприклад, замість:
/".*?"/gможна використати:
/"[^"]*"/gКлас [^"] означає «будь-який символ, крім лапки».
const text = 'Імена: "Анна", "Олег", "Марія"';
console.log(text.match(/"[^"]*"/g));
// [ '"Анна"', '"Олег"', '"Марія"' ]Такий шаблон чітко описує правило: між лапками не може бути іншої лапки.
Це допомагає:
краще передати задум регулярного виразу;
уникнути зайвих збігів;
зменшити кількість перевірок під час пошуку.
Нехай потрібно знайти всі хештеги в повідомленні. Хештег починається з #, після якого йдуть одна або більше літер, цифр або символів підкреслення.
const message = "Вивчаю #JavaScript та #Regular_Expressions у #2025.";
const hashtagPattern = /#[A-Za-z0-9_]+/g;
const hashtags = message.match(hashtagPattern) ?? [];
console.log(hashtags);
// [ '#JavaScript', '#Regular_Expressions', '#2025' ]Розберімо шаблон:
# — звичайний символ решітки;
[A-Za-z0-9_] — латинські літери, цифри або _;
+ — один або більше таких символів;
g — знайти всі збіги;
?? [] — використати порожній масив, якщо збігів немає.
Ще один приклад — перевірка номера замовлення:
function isValidOrderNumber(value) {
return /^ORD-\d{6}$/.test(value);
}
console.log(isValidOrderNumber("ORD-123456")); // true
console.log(isValidOrderNumber("ORD-12345")); // false
console.log(isValidOrderNumber("ORD-1234567")); // falseУ цьому шаблоні:
^ означає початок рядка;
ORD- — обов’язкова частина;
\d{6} — рівно шість цифр;
$ означає кінець рядка.
Квантифікатори * і ? можуть відповідати нульовій кількості символів.
const pattern = /a*/g;
console.log("bbb".match(pattern));
// [ '', '', '', '' ]Між символами рядка немає a, тому a* успішно відповідає порожньому фрагменту в кожній позиції, де це можливо.
Через це шаблони з * можуть давати неочікувані результати. Якщо символ має бути присутнім, використовуйте +:
console.log("bbb".match(/a+/g)); // null/ab+/ // "a" і один або більше символів "b"
/(ab)+/ // одна або більше груп "ab"Якщо потрібно повторювати кілька символів, використовуйте групу:
const wrong = /ha{2}/;
const correct = /(ha){2}/;
console.log("haha".match(wrong)); // null
console.log("haha".match(correct)); // [ 'haha' ]* і +/a*/ // збігається навіть із порожнім фрагментом
/a+/ // вимагає щонайменше одну "a"Якщо значення не повинно бути порожнім, зазвичай потрібен +, а не *.
gБез g метод match() повертає лише перший знайдений збіг:
const text = "one two three";
console.log(text.match(/\w+/));
// [ 'one', index: 0, input: 'one two three', groups: undefined ]
console.log(text.match(/\w+/g));
// [ 'one', 'two', 'three' ]Шаблон .* може захопити більше тексту, ніж потрібно:
const text = "[один] [два]";
console.log(text.match(/\[.*\]/));
// [ '[один] [два]' ]Для окремих блоків можна використати ледачий варіант:
console.log(text.match(/\[.*?\]/g));
// [ '[один]', '[два]' ]Або точніший клас символів:
console.log(text.match(/\[[^\]]*\]/g));
// [ '[один]', '[два]' ]{n,m}У {n,m} значення n не може бути більшим за m:
/\d{4,2}/ // некоректна логіка діапазонуЯкщо потрібні чотири або більше цифр, використовуйте:
/\d{4,}/console.log(/\d{4}/.test("abc2025xyz")); // trueШаблон знайшов чотири цифри всередині рядка. Для перевірки всього рядка використовуйте ^ і $:
console.log(/^\d{4}$/.test("abc2025xyz")); // false
console.log(/^\d{4}$/.test("2025")); // trueКвантифікатори задають кількість повторень елемента регулярного виразу.
* означає нуль або більше повторень.
+ означає одне або більше повторень.
? означає нуль або одне повторення.
{n} задає рівно n повторень.
{n,} задає щонайменше n повторень.
{n,m} задає від n до m повторень.
За замовчуванням квантифікатори жадібні та намагаються захопити якомога більше тексту.
Додавання ? після квантифікатора робить його ледачим.
Для повторення кількох символів використовуйте групи: (ab)+.
Для перевірки всього рядка використовуйте якорі ^ і $.
Квантифікатори * і ? можуть створювати порожні збіги, тому їх потрібно застосовувати уважно.