Пошук уроків, статей та іншого контенту
Порівняєте прапорці g, i, m, s, u, y і d та побачите, як вони змінюють поведінку пошуку.
Прапорці регулярного виразу — це параметри, які змінюють правила його роботи. Вони записуються після завершального символу /:
const pattern = /javascript/gi;У цьому прикладі:
g вмикає глобальний пошук;
i вимикає врахування регістру.
RegExpconst pattern = new RegExp("javascript", "gi");Доступні прапорці можна прочитати через властивість flags:
const pattern = /javascript/gi;
console.log(pattern.flags); // "gi"Один і той самий прапорець не можна вказати двічі:
// SyntaxError
const pattern = /test/gg;g: глобальний пошукБез g регулярний вираз зазвичай знаходить лише перший збіг.
const text = "JavaScript — це JavaScript.";
console.log(text.match(/JavaScript/));
// [ 'JavaScript', index: 0, input: 'JavaScript ...', groups: undefined ]
console.log(text.match(/JavaScript/g));
// [ 'JavaScript', 'JavaScript' ]Прапорець g особливо важливий для таких методів:
String.prototype.match();
String.prototype.matchAll();
String.prototype.replace();
String.prototype.search() — тут g не змінює результат, оскільки метод шукає лише позицію першого збігу;
RegExp.prototype.exec().
g і метод replaceconst text = "red red blue";
console.log(text.replace(/red/, "green"));
// "green red blue"
console.log(text.replace(/red/g, "green"));
// "green green blue"Без g замінюється лише перший збіг.
g і lastIndexГлобальний регулярний вираз зберігає позицію наступного пошуку у властивості lastIndex:
const pattern = /\d/g;
const text = "a1b2c3";
console.log(pattern.exec(text)); // [ '1', ... ]
console.log(pattern.lastIndex); // 2
console.log(pattern.exec(text)); // [ '2', ... ]
console.log(pattern.lastIndex); // 4
console.log(pattern.exec(text)); // [ '3', ... ]
console.log(pattern.lastIndex); // 6
console.log(pattern.exec(text)); // null
console.log(pattern.lastIndex); // 0Після невдалого пошуку lastIndex скидається в 0.
Через це один і той самий глобальний регулярний вираз не варто бездумно використовувати в різних незалежних операціях:
const pattern = /cat/g;
console.log(pattern.test("cat")); // true
console.log(pattern.test("cat")); // falseДругий виклик починає пошук із позиції, збереженої після першого виклику.
Щоб почати пошук спочатку, можна скинути lastIndex вручну:
pattern.lastIndex = 0;i: ігнорування регіструПрапорець i робить пошук нечутливим до регістру:
const pattern = /javascript/i;
console.log(pattern.test("JavaScript")); // true
console.log(pattern.test("JAVASCRIPT")); // true
console.log(pattern.test("javascript")); // trueБез i регістр має значення:
console.log(/javascript/.test("JavaScript")); // falsei можна поєднувати з іншими прапорцями:
const text = "JavaScript javascript JAVASCRIPT";
console.log(text.match(/javascript/gi));
// [ 'JavaScript', 'javascript', 'JAVASCRIPT' ]Прапорець i не змінює сам текст і не перетворює результат на нижній регістр. Він лише змінює правила порівняння символів.
m: багаторядковий режимПрапорець m змінює поведінку якорів:
^ починає збіг із початком кожного рядка;
$ завершує збіг у кінці кожного рядка.
Без m ^ і $ працюють лише з початком і кінцем усього рядка:
const text = `first line
second line
third line`;
console.log(text.match(/^.+$/));
// nullРегулярний вираз . за замовчуванням не збігається з символом перенесення рядка, тому весь багаторядковий текст не підходить під один збіг.
Увімкнемо m і використаємо глобальний пошук:
const text = `first line
second line
third line`;
console.log(text.match(/^.+$/gm));
// [ 'first line', 'second line', 'third line' ]Тут:
g знаходить усі рядки;
m дозволяє ^ і $ працювати для кожного рядка окремо;
. знаходить символи всередині рядка, але не сам перенос рядка.
const log = `INFO: Server started
ERROR: Database unavailable
INFO: Request completed`;
const errors = log.match(/^ERROR:.*$/gm);
console.log(errors);
// [ 'ERROR: Database unavailable' ]Прапорець m не означає «знайти кілька рядків» сам по собі. Для отримання всіх збігів зазвичай також потрібен g.
s: режим dotAllЗа замовчуванням крапка . збігається майже з будь-яким символом, крім:
перенесення рядка \n;
повернення каретки \r;
розділювача рядків \u2028;
розділювача абзаців \u2029.
Прапорець s дозволяє крапці збігатися і з цими символами.
const text = `begin
middle
end`;
console.log(/^begin.*end$/.test(text));
// false
console.log(/^begin.*end$/s.test(text));
// trueУ цьому прикладі .* із прапорцем s може перейти через перенесення рядка.
Властивість dotAll показує, чи активний цей прапорець:
console.log(/./s.dotAll); // true
console.log(/./.dotAll); // falses і m вирішують різні задачіЦі прапорці часто використовують разом, але вони впливають на різні частини виразу:
s дозволяє . збігатися з перенесенням рядка;
m змінює поведінку ^ і $.
const text = `title
line 1
line 2
footer`;
const result = text.match(/^title.*footer$/ms);
console.log(result[0]);
// title
// line 1
// line 2
// footeru: UnicodeПрапорець u вмикає Unicode-режим. Він важливий для:
коректної роботи з символами, представленими парою UTF-16-кодів;
Unicode escape-послідовностей на кшталт \u{1F600};
суворішого аналізу синтаксису регулярного виразу.
JavaScript зберігає рядки у форматі UTF-16. Деякі символи Unicode займають дві 16-бітні кодові одиниці.
Без u регулярний вираз може сприймати такий символ як два окремі елементи:
const smile = "😀";
console.log(smile.length); // 2
console.log(/^.$/.test(smile)); // false
console.log(/^.$/u.test(smile)); // trueЗ прапорцем u крапка сприймає 😀 як один Unicode-символ.
У режимі u можна використовувати запис \u{...} із кодовою точкою:
const smile = /\u{1F600}/u;
console.log(smile.test("😀")); // trueБез u такий запис не має тієї самої семантики.
Прапорець u потрібен для Unicode-властивостей, наприклад:
const text = "JavaScript 2025";
console.log(text.match(/\p{Letter}+/gu));
// [ 'JavaScript' ]Тут:
\p{Letter} означає символ Unicode-категорії «літера»;
u вмикає підтримку Unicode-властивостей;
g знаходить усі групи літер.
Можна використовувати й коротку форму:
const numbers = "Room 42, floor 7";
console.log(numbers.match(/\p{Number}+/gu));
// [ '42', '7' ]Підтримка Unicode-властивостей потребує прапорця u. Без нього такий регулярний вираз завершується помилкою синтаксису.
y: sticky-пошукПрапорець y називають sticky, тобто «липким». Він змушує регулярний вираз шукати збіг точно з позиції lastIndex.
На відміну від g, прапорець y не шукає далі, якщо в поточній позиції збігу немає.
const text = "123 abc";
const globalPattern = /\w+/g;
const stickyPattern = /\w+/y;
globalPattern.lastIndex = 4;
stickyPattern.lastIndex = 4;
console.log(globalPattern.exec(text)[0]);
// "abc"
console.log(stickyPattern.exec(text));
// nullНа позиції 4 у рядку розташований пробіл. Глобальний вираз пропускає його і знаходить abc, а sticky-вираз вимагає збіг саме з позиції 4.
Якщо встановити lastIndex на початок слова:
stickyPattern.lastIndex = 5;
console.log(stickyPattern.exec(text)[0]);
// "abc"ySticky-режим зручний для послідовного розбору тексту, коли кожен наступний елемент має починатися саме там, де завершився попередній:
const input = "42 + 8";
const number = /\d+/y;
const operator = /[+]/y;
number.lastIndex = 0;
const firstNumber = number.exec(input);
operator.lastIndex = number.lastIndex + 1;
const plus = operator.exec(input);
number.lastIndex = operator.lastIndex + 1;
const secondNumber = number.exec(input);
console.log(firstNumber[0]); // "42"
console.log(plus[0]); // "+"
console.log(secondNumber[0]); // "8"У реальному парсері позицію пробілів зазвичай обробляють окремо. Головна ідея y: регулярний вираз не має права «перестрибнути» через невідповідний текст.
Прапорці g і y обидва використовують lastIndex, але мають різну поведінку:
g може шукати наступний збіг далі в рядку;
y перевіряє лише позицію lastIndex.
d: індекси збігівПрапорець d вмикає запис індексів кожного збігу. Результат exec() або matchAll() тоді містить властивість indices.
const text = "ID: A42";
const pattern = /([A-Z])(\d+)/d;
const result = pattern.exec(text);
console.log(result[0]); // "A42"
console.log(result.indices); // [ [ 4, 7 ], [ 4, 5 ], [ 5, 7 ] ]Індекси мають формат [початок, кінець]. Кінцева позиція не входить у збіг, як і в методах slice() та substring().
У цьому прикладі:
result[0] — весь збіг A42, індекси [4, 7];
result[1] — літера A, індекси [4, 5];
result[2] — число 42, індекси [5, 7].
Індекси можна використати для вилучення фрагментів оригінального рядка:
const text = "ID: A42";
const pattern = /([A-Z])(\d+)/d;
const result = pattern.exec(text);
const [start, end] = result.indices[0];
console.log(text.slice(start, end)); // "A42"Для іменованих груп індекси доступні через indices.groups:
const text = "2025-07-26";
const pattern =
/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/d;
const result = pattern.exec(text);
console.log(result.indices.groups);
// { year: [ 0, 4 ], month: [ 5, 7 ], day: [ 8, 10 ] }Якщо необов’язкова група не взяла участі у збігу, її індекси матимуть значення undefined.
Прапорці зазвичай комбінують, щоб отримати потрібну поведінку:
const text = `Email: FIRST@example.com
Email: second@example.com`;
const emails = text.match(
/[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}/gim
);
console.log(emails);
// [ 'FIRST@example.com', 'second@example.com' ]Тут:
g знаходить усі адреси;
i ігнорує регістр;
m дозволяє якорям працювати з окремими рядками.
Однак у цьому конкретному виразі m не є обов’язковим, оскільки в ньому немає ^ або $. Наявність прапорця, який не впливає на вираз, не змінює результат, але може вводити в оману.
Поширене поєднання для обробки багаторядкового тексту:
const block = `BEGIN
content line 1
content line 2
END`;
const match = block.match(/^BEGIN.*?^END$/ms);
console.log(match[0]);
// BEGIN
// content line 1
// content line 2
// ENDТут:
m дозволяє ^END збігтися з початком окремого рядка;
s дозволяє .*? проходити через перенесення рядків;
? робить квантифікатор «ледачим», щоб знайти найближчий END.
Для перевірки прапорців існують спеціальні властивості:
const pattern = /test/gimsuyd;
console.log(pattern.global); // true
console.log(pattern.ignoreCase); // true
console.log(pattern.multiline); // true
console.log(pattern.dotAll); // true
console.log(pattern.unicode); // true
console.log(pattern.sticky); // true
console.log(pattern.hasIndices); // trueНазви властивостей:
global — g;
ignoreCase — i;
multiline — m;
dotAll — s;
unicode — u;
sticky — y;
hasIndices — d.
gconst text = "one two one";
console.log(text.match(/one/));
// лише перший збіг
console.log(text.match(/one/g));
// усі збігиЯкщо потрібно отримати всі збіги, перевірте наявність g.
g і yconst text = " 123";
const globalPattern = /\d+/g;
const stickyPattern = /\d+/y;
globalPattern.lastIndex = 0;
stickyPattern.lastIndex = 0;
console.log(globalPattern.exec(text)[0]); // "123"
console.log(stickyPattern.exec(text)); // nullg може пропустити пробіл і знайти число далі. y вимагає, щоб число починалося саме з нульової позиції.
m дозволить крапці переходити через рядкиm не змінює поведінку крапки:
const text = "first\nsecond";
console.log(/first.*second/m.test(text)); // false
console.log(/first.*second/s.test(text)); // trueДля переходу крапки через перенесення рядка потрібен s.
^ і $ замість пошуку повного рядкаУ JavaScript $ перед завершальним переносом рядка може збігатися до цього переносу. Якщо потрібно перевірити точну структуру всього рядка, уважно обирайте якорі та додаткову логіку перевірки.
Також пам’ятайте: m змінює ^ і $ для кожного рядка, тому вираз із ^ або $ може почати збігатися в більшій кількості позицій, ніж очікувалося.
u лише для Unicode-текстуПрапорець u не «перекладає» рядок і не нормалізує різні форми Unicode. Він змінює правила інтерпретації регулярного виразу та кодових точок.
Наприклад, візуально подібні символи можуть мати різні кодові послідовності. Для таких випадків окремо може знадобитися нормалізація рядка через String.prototype.normalize().
lastIndexГлобальні та sticky-регулярні вирази мають стан:
const pattern = /a/g;
console.log(pattern.test("a")); // true
console.log(pattern.test("a")); // falseЯкщо ви повторно використовуєте такий вираз, контролюйте lastIndex або створюйте новий екземпляр регулярного виразу.
d без перевірки середовищаПрапорець d підтримується сучасними середовищами JavaScript. Якщо код має працювати в застарілому браузері або старій версії рушія, можливість підтримки цього прапорця потрібно перевірити окремо.
g знаходить усі збіги та використовує lastIndex.
i вимикає врахування регістру.
m змінює роботу ^ і $, дозволяючи їм працювати з кожним рядком.
s дозволяє крапці . збігатися з перенесеннями рядків.
u вмикає коректнішу роботу з Unicode-кодовими точками та Unicode-властивостями.
y шукає збіг лише з позиції lastIndex і не перестрибує невідповідний текст.
d додає індекси початку й кінця збігів у властивість indices.
Прапорці можна комбінувати, але кожен із них має окрему відповідальність.
Для g і y важливо враховувати стан lastIndex.