RegExp.prototype.exec()

Метод exec() (виконати) примірників RegExp виконує пошук збігу свого регулярного виразу в заданому рядку й повертає результівний масив або null.

Спробуйте його в дії

Синтаксис

exec(str)

Параметри

str

Рядок, з котрим зіставляється регулярний вираз. Будь-які значення зводяться до рядків, тож пропуск цього параметра або передача в ньому undefined змусить exec() шукати рядок "undefined", а це рідко саме те, що необхідно.

Повернене значення

Якщо зіставлення не вдається, то метод exec() повертає null і присвоює властивості регулярного виразу lastIndex значення 0.

Якщо зіставлення вдається, то метод exec() повертає масив і оновлює властивість lastIndex об'єкта регулярного виразу. Повернений масив містить текст збігу на першій позиції, а далі – по одному елементу на кожну групу захоплення в тексті збігу. Цей масив також має наступні додаткові властивості:

index

Індекс збігу в рядку, з нумерацією від нуля.

input

Вихідний рядок, з котрим відбувалось зіставлення.

groups

Об'єкт з прототипом null іменованих груп захоплення, чиї ключі – імена цих груп, а значення – самі групи, або undefined, якщо не була визначена жодна іменована група захоплення. Дивіться більше інформації на сторінці груп захоплення.

indices Необов'язкове

Ця властивість присутня лише тоді, коли задана позначка d. Це масив, кожен елемент якого представляє межі збігу підрядка. Індекс кожного елемента цього масиву відповідає індексові в масиві, поверненому exec(), відповідного збігу підрядка. Інакше кажучи, перший запис indices представляє ввесь збіг, другий – першу групу захоплення, і так далі. Кожний запис сам по собі є двоелементним масивом, у якого перше число представляє індекс початку збігу, а друге – індекс кінця.

Крім цього, масив indices має властивість groups, котра зберігає об'єкт з прототипом null, що містить усі іменовані групи захоплення. Його ключі – імена цих груп, а значення – масиви з двох елементів, у яких перше число – індекс початку, а друге – індекс кінця групи захоплення. Якщо регулярний вираз не містить жодних іменованих груп захоплення, то groups отримує значення undefined.

Опис

Об'єкти JavaScript RegExp мають стан, коли мають позначку глобальності чи липкості (наприклад, /foo/g або /foo/y). Вони зберігають lastIndex від попереднього зіставлення. Завдяки неявному використанню цієї властивості exec() можна використовувати для ітерації по багатьох збігах у рядку тексту (з групами захоплення), а не просто отримувати рядки збігу за допомогою String.prototype.match().

При використанні exec() позначка глобальності не діє за присутності позначки липкості: зіставлення обов'язково буде липким.

exec() – примітивний метод регулярних виразів. Чимало інших їхніх методів неявно викликають exec() – включно з тими, що викликаються методами рядків, як то [Symbol.replace](). Хоч сам по собі exec() є потужним (і найефективнішим), він нерідко не доносить намір розробника якнайясніше.

  • Якщо важливо лише те, чи збігається регулярний вираз із рядком, але не сам текст збігу, варто натомість використати RegExp.prototype.test().
  • Якщо шукаються усі входження глобального регулярного виразу, і неважлива інформація штибу груп захоплення, варто натомість використати String.prototype.match(). На додачу: String.prototype.matchAll() допомагає шукати збіг з багатьма частинами рядка (з групами захоплення), даючи змогу ітерувати по збігах.
  • Якщо зіставлення виконується для пошуку індексу початку збігу в рядку, варто натомість використати String.prototype.search().

Приклади

Застосування exec()

Для прикладу:

// Знайти "quick brown", після чого є "jumps", ігноруючи символи між цими частинами
// Запам'ятати "brown" і "jumps"
// Ігнорувати регістр
const re = /quick\s(?<color>brown).+?(jumps)/dgi;
const result = re.exec("The Quick Brown Fox Jumps Over The Lazy Dog");

Наступна таблиця демонструє стан result після роботи цього сценарію

Властивість Значення
[0] "Quick Brown Fox Jumps"
[1] "Brown"
[2] "Jumps"
index 4
indices [[4, 25], [10, 15], [20, 25]]
groups: { color: [10, 15 ]}
input "The Quick Brown Fox Jumps Over The Lazy Dog"
groups { color: "brown" }

На додачу, re.lastIndex отримала значення 25, адже цей регулярний вираз є глобальним.

Пошук послідовних збігів

Коли регулярний вираз застосовує позначку g, можна використовувати метод exec() багато разів для отримання послідовних збігів у тому самому рядку. У такому випадку пошук починається від підрядка str, заданого властивістю регулярного виразу lastIndex (test() також посуває властивість lastIndex). Зверніть увагу, що властивість lastIndex не скидається при пошуку в іншому рядку, а почне пошук згідно з наявним значенням lastIndex.

Наприклад, припустімо, є такий сценарій:

const myRe = /ab*/g;
const str = "abbcdefabh";
let myArray;
while ((myArray = myRe.exec(str)) !== null) {
  let msg = `Знайдено ${myArray[0]}. `;
  msg += `Наступне зіставлення починається від ${myRe.lastIndex}`;
  console.log(msg);
}

Цей сценарій виведе наступний текст:

Знайдено abb. Наступне зіставлення починається від 3
Знайдено ab. Наступне зіставлення починається від 9

Застереження: Є чимало підводних каменів, котрі можуть привести цю функціональність до нескінченного циклу!

  • Ніколи не ставте літерал регулярного виразу (або конструктор RegExp) всередину умови while: це буде створювати регулярний вираз заново для кожної ітерації та скидати lastIndex.
  • Перевірте, що заданий прапорець глобальності (g), інакше lastIndex ніколи не буде посунуто.
  • Якщо регулярний вираз може дати збіг з символами нульової довжини (наприклад, /^/gm), збільшуйте його lastIndex щоразу вручну, інакше застрягнете в одному місці.

Зазвичай код такого роду можна замінити String.prototype.matchAll(), аби зробити його надійнішим.

Застосування exec() з літералами RegExp

Також exec() можна застосовувати без явного створення об'єкта RegExp:

const matches = /(hello \S+)/.exec("This is a hello world!");
console.log(matches[1]);

Це виведе повідомлення, що містить 'hello world!'.

Специфікації

Сумісність із браузерами

desktop mobile server
Chrome Edge Firefox Internet Explorer Opera Safari WebView Android Chrome Android Firefox for Android Opera Android Safari on iOS Samsung Internet Deno Node.js
exec
Chrome Full support 1
Edge Full support 12
Firefox Full support 1
Internet Explorer Full support 4
Opera Full support 5
Safari Full support 1
WebView Android Full support 1
Chrome Android Full support 18
Firefox for Android Full support 4
Opera Android Full support 10.1
Safari on iOS Full support 1
Samsung Internet Full support 1.0
Deno Full support 1.0
Node.js Full support 0.10.0

Дивіться також