24 травня 2023 р.

Зворотні посилання в шаблоні: \N і \k<ім’я>

Вміст груп захоплення (...) можна використовувати не тільки в резульаті пошуку чи рядку заміни, а й також безпосередньо у самому шаблоні.

Зворотнє посилання за номером: \N

До групи можна посилатися в шаблоні використовуючи \N, де N – номер групи.

Для того, аби зрозуміти, чим це може бути корисним, давайте розглянемо приклад.

Потрібно знайти рядки в лапках: або в одинарних '...', або в подвійних "..." – обидва варіанти повинні збігатися.

Як їх знайти?

Ми можемо розмістити обидва типи лапок у квадратних дужках: ['"](.*?)['"], але цей вираз знайде рядки зі змішаними лапками, наприклад "...' і '...". Це призведе до неправильних збігів, коли один тип лапок буде в середині інших, наприклад в рядку "Яке твоє ім'я?":

let str = `Він запитав: "Яке твоє ім'я?".`;

let regexp = /['"](.*?)['"]/g;

// Результат не той, який ми б хотіли мати
alert( str.match(regexp) ); // "Яке твоє ім'

Як видно, шаблон знайшов початкову подвійну лапку ", потім текст, включно до наступної одинарної лапки ', опісля чого пошук завершився.

Щоб бути впевненим, що шаблон шукає таку ж кінцеву лапку, як і початкову, можемо обернути початкові лапки в групу захвату і задіяти зворотнє посилання: (['"])(.*?)\1.

Ось правильний код:

let str = `Він запитав: "Яке твоє ім'я?".`;

let regexp = /(['"])(.*?)\1/g;

alert( str.match(regexp) ); // "Яке твоє ім'я?"

Все працює! Механізм регулярних виразів знаходить першу лапку (['"]) та запамʼятовує її. Це перша група захоплення.

Далі в шаблоні \1 означає: “знайти такий же текст, як і в першій групі”, що в нашому випадку – таку ж саму лапку.

Подібно до цього, \2 означало б вміст другої групи, \3 – 3-ї групи, і так далі.

Будь ласка, зверніть увагу:

Ми не можемо посилатися на групу, якщо в ній задіяно ?:. Групи, які були виключені із захоплення (?:...), не запамʼятовуються механізмом регулярних виразів.

Не переплутайте: в шаблоні \1, при заміні: $1

У рядку заміни використовується знак долара: $1, а в шаблоні – обернена коса риска \1.

Зворотнє посилання за назвою: \k<імʼя>

Якщо регулярний вираз має багато дужок, досить зручно в такому випадку давати їм імена.

Для посилання на іменовану групу можна використовувати \k<імʼя>.

У наведеному нижче прикладі група з лапками називається ?<quote>, тому звернення до нього буде \k<quote>:

let str = `Він запитав: "Яке твоє ім'я?".`;

let regexp = /(?<quote>['"])(.*?)\k<quote>/g;

alert( str.match(regexp) ); // "Яке твоє ім'я?"
Навчальна карта

Коментарі

прочитайте це, перш ніж коментувати…
  • Якщо у вас є пропозиції, щодо покращення підручника, будь ласка, створіть обговорення на GitHub або одразу створіть запит на злиття зі змінами.
  • Якщо ви не можете зрозуміти щось у статті, спробуйте покращити її, будь ласка.
  • Щоб вставити код, використовуйте тег <code>, для кількох рядків – обгорніть їх тегом <pre>, для понад 10 рядків – використовуйте пісочницю (plnkr, jsbin, codepen…)