String.prototype.matchAll()

Метод matchAll() повертає ітератор з усіма результатами зіставлення рядка з регулярним виразом, в тому числі групи захоплення.

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

Синтаксис

matchAll(regexp)

Параметри

regexp

Об'єкт регулярного виразу.

Якщо до методу передається не регулярний вираз, а інший об'єкт obj, він неявним чином конвертується у регулярний вираз шляхом виконання виразу new RegExp(obj).

Переданий регулярний вираз мусить мати прапорець /g, інакше буде викинуто помилку TypeError.

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

Метод повертає ітератор зі знайденими збігами (непридатний до повторного перебирання).

Кожен збіг є масивом (з двома додатковими властивостями index та input; докладніше про це в описі поверненого значення методу RegExp.exec). Масив збігів містить першим елементом знайдений текст, за яким йдуть всі знайдені збіги для груп захоплення, зазначених в дужках.

Приклади

Методи Regexp.exec() і matchAll()

До появи методу matchAll в JavaScript було можливо викликати regexp.exec (на регулярних виразах з прапорцем /g) в циклі для отримання всіх збігів:

const regexp = new RegExp('foo[a-z]*','g');
const str = 'table football, foosball';
let match;

while ((match = regexp.exec(str)) !== null) {
  console.log(`Знайдено слово ${match[0]}, початок=${match.index}, закінчення=${regexp.lastIndex}.`);
  // очікуваний вивід: "Знайдено слово football, початок=6, закінчення=14."
  // очікуваний вивід: "Знайдено слово foosball, початок=16, закінчення=24."
}

За наявності методу matchAll є можливість уникати циклу while і використання методу exec із g.

Натомість під час роботи з matchAll створюється ітератор, який можна використати зі зручнішими конструкціями for...of, array spread, чи Array.from():

const regexp = new RegExp('foo[a-z]*','g');
const str = 'table football, foosball';
const matches = str.matchAll(regexp);

for (const match of matches) {
  console.log(`Знайдено слово ${match[0]}, початок=${match.index}, закінчення=${match.index + match[0].length}.`);
}
// очікуваний вивід: "Знайдено слово football, початок=6, закінчення=14."
// очікуваний вивід: "Знайдено слово foosball, початок=16, закінчення=24."

// ітератор зі збігами вичерпується після перебирання у for..of
// Новий виклик matchAll створить новий ітератор
Array.from(str.matchAll(regexp), m => m[0]);
// Array [ "football", "foosball" ]

Якщо прапорець g опущено, метод matchAll викине виняток.

const regexp = new RegExp('[a-c]','');
const str = 'abc';
str.matchAll(regexp);
// TypeError

Метод matchAll для своїх потреб створює клон глобального об'єкта RegExp. Тому, на відміну від використання методу regexp.exec(), властивість lastIndex об'єкта RegExp не змінюється під час сканування рядка.

const regexp = new RegExp('[a-c]','g');
regexp.lastIndex = 1;
const str = 'abc';
Array.from(str.matchAll(regexp), m => `${regexp.lastIndex} ${m[0]}`);
// Array [ "1 b", "1 c" ]

Кращий доступ до груп захоплення (ніж у String.prototype.match())

Іншою привабливою причиною використати matchAll є покращений доступ до груп захоплення.

Під час застосування match() з прапорцем глобального пошуку /g групи захоплення ігноруються:

let regexp = /t(e)(st(\d?))/g;
let str = 'test1test2';

str.match(regexp);
// Array ['test1', 'test2']

За допомогою matchAll можна легко отримати доступ до груп:

let array = [...str.matchAll(regexp)];

array[0];
// ['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', length: 4]
array[1];
// ['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', length: 4]

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

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

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
matchAll
Chrome Full support 73
Edge Full support 79
Firefox Full support 67
Internet Explorer No support No
Opera Full support 60
Safari Full support 13
WebView Android Full support 73
Chrome Android Full support 73
Firefox for Android Full support 67
Opera Android Full support 52
Safari on iOS Full support 13
Samsung Internet Full support 11.0
Deno Full support 1.0
Node.js Full support 12.0.0

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