String.prototype.matchAll()
Базовая поддержка Широко доступна
Эта функция хорошо зарекомендовала себя и работает на многих устройствах и версиях браузеров. Она доступна в браузерах с января 2020 года.
Метод matchAll() значений String возвращает итератор всех результатов, соответствующих этой строке, по регулярному выражению, включая группы захвата.
Попробуйте
const regexp = /t(e)(st(\d?))/g; const str = "test1test2"; const array = [...str.matchAll(regexp)]; console.log(array[0]); // Expected output: Array ["test1", "e", "st1", "1"] console.log(array[1]); // Expected output: Array ["test2", "e", "st2", "2"]
Синтаксис
matchAll(regexp)
Параметры
-
regexp -
Объект регулярного выражения или любой объект, имеющий метод
Symbol.matchAll.Если
regexpне является объектомRegExpи не имеет методаSymbol.matchAll, он неявно преобразуется вRegExpс помощьюnew RegExp(regexp, 'g').Если
regexpявляется регулярным выражением, то должен быть установлен глобальный флаг (g), иначе будет выброшеноTypeError.
Возвращаемое значение
Объект итератора (не возобновляемый) с возможностью итерации (iterable iterator object) совпадений или пустой итератор, если совпадений не найдено. Каждое значение, возвращаемое итератором, представляет собой массив той же формы, что и возвращаемое значение RegExp.prototype.exec().
Исключения
-
TypeError - Выбрасывается, если
regexpявляется регулярным выражением, у которого не установлен глобальный флаг (g) (его свойствоflagsне содержит"g").
Описание
Реализация String.prototype.matchAll не делает ничего, кроме вызова метода Symbol.matchAll аргумента с строкой в качестве первого параметра (помимо дополнительной проверки входных данных на глобальность регулярного выражения). Фактическая реализация поступает из RegExp.prototype[Symbol.matchAll]().
Примеры
Regexp.prototype.exec() и matchAll()
Без matchAll() можно использовать вызовы regexp.exec() (и регулярных выражений с флагом g) в цикле для получения всех совпадений:
const regexp = /foo[a-z]*/g;
const str = "table football, foosball";
let match;
while ((match = regexp.exec(str)) !== null) {
console.log(
`Found ${match[0]} start=${match.index} end=${regexp.lastIndex}.`,
);
}
// Found football start=6 end=14.
// Found foosball start=16 end=24.
С доступным matchAll() вы можете избежать цикла while и exec с g. Вместо этого вы получаете итератор для использования с более удобным for...of, расширением массива или конструкциями Array.from():
const regexp = /foo[a-z]*/g;
const str = "table football, foosball";
const matches = str.matchAll(regexp);
for (const match of matches) {
console.log(
`Found ${match[0]} start=${match.index} end=${
match.index + match[0].length
}.`,
);
}
// Found football start=6 end=14.
// Found foosball start=16 end=24.
// matches iterator is exhausted after the for...of iteration
// Call matchAll again to create a new iterator
Array.from(str.matchAll(regexp), (m) => m[0]);
// [ "football", "foosball" ]
matchAll вызовет исключение, если отсутствует флаг g.
const regexp = /[a-c]/; const str = "abc"; str.matchAll(regexp); // TypeError
matchAll внутренне создает копию regexp — поэтому, в отличие от regexp.exec(), lastIndex не изменяется при сканировании строки.
const regexp = /[a-c]/g;
regexp.lastIndex = 1;
const str = "abc";
Array.from(str.matchAll(regexp), (m) => `${regexp.lastIndex} ${m[0]}`);
// [ "1 b", "1 c" ]
Однако это означает, что в отличие от использования regexp.exec() в цикле, вы не можете изменять lastIndex, чтобы заставить регулярное выражение продвигаться или отступать.
Лучший доступ к группам захвата (чем у String.prototype.match())
Еще одна убедительная причина для matchAll — улучшенный доступ к группам захвата.
Группы захвата игнорируются при использовании match() с глобальным флагом g:
const regexp = /t(e)(st(\d?))/g; const str = "test1test2"; str.match(regexp); // ['test1', 'test2']
Используя matchAll, вы можете легко получить доступ к группам захвата:
const 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]
Использование matchAll() с не-RegExp, реализующим [Symbol.matchAll]()
Если объект имеет метод Symbol.matchAll, его можно использовать в качестве пользовательского матчера. Возвращаемое значение Symbol.matchAll становится возвращаемым значением matchAll().
const str = "Hmm, this is interesting.";
str.matchAll({
[Symbol.matchAll](str) {
return [["Yes, it's interesting."]];
},
}); // returns [["Yes, it's interesting."]]
Спецификации
Совместимость с браузерами
| Desktop | Mobile | Server | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on iOS | Samsung Internet | WebView Android | WebView on iOS | Bun | Deno | Node.js | |
matchAll |
73 |
79 |
67 |
60 |
13 |
73 |
67 |
52 |
13 |
11.0 |
73 |
13 |
1.0.0 |
1.0 |
12.0.0 |
См. также
- Polyfill
String.prototype.matchAllвcore-js - es-shims polyfill
String.prototype.matchAll - Руководство по регулярным выражениям
- Руководство по группам и обратным ссылкам
String.prototype.match()RegExpRegExp.prototype.exec()RegExp.prototype.test()RegExp.prototype[Symbol.matchAll]()
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/matchAll