String.prototype.matchAll()
Baseline
Weitgehend verfügbar
Diese Funktion ist gut etabliert und funktioniert auf vielen Geräten und in vielen Browserversionen. Sie ist seit Januar 2020 browserübergreifend verfügbar.
Die Methode matchAll() von String-Werten gibt einen Iterator über alle Ergebnisse zurück, die beim Abgleich dieses Strings mit einem regulären Ausdruck gefunden werden, einschließlich der Erfassungsgruppen.
Probieren Sie es aus
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"]
Syntax
matchAll(regexp)
Parameter
regexp-
Ein Objekt für reguläre Ausdrücke oder ein beliebiges Objekt mit einer
Symbol.matchAll-Methode.Wenn
regexpkeinRegExp-Objekt ist und keineSymbol.matchAll-Methode besitzt, wird es mitnew RegExp(regexp, 'g')implizit in einRegExpumgewandelt.Wenn
regexpein regulärer Ausdruck ist, muss das globale Flag (g) gesetzt sein. Andernfalls wird einTypeErrorausgelöst.
Rückgabewert
Ein iterierbares Iteratorobjekt (das nicht neu gestartet werden kann), das Treffer liefert, oder ein leerer Iterator, wenn keine Treffer gefunden werden. Jeder vom Iterator gelieferte Wert ist ein Array mit derselben Struktur wie der Rückgabewert von RegExp.prototype.exec().
Ausnahmen
TypeError-
Wird ausgelöst, wenn
regexpein regulärer Ausdruck ist, bei dem das globale Flag (g) nicht gesetzt ist (dessen Eigenschaftflagsalso kein"g"enthält).
Beschreibung
Die Implementierung von String.prototype.matchAll ruft im Wesentlichen nur die Symbol.matchAll-Methode des Arguments mit dem String als erstem Parameter auf (abgesehen von der zusätzlichen Prüfung, ob der reguläre Ausdruck global ist). Die eigentliche Implementierung stammt von RegExp.prototype[Symbol.matchAll]().
Beispiele
>Regexp.prototype.exec() und matchAll()
Ohne matchAll() können Sie regexp.exec() (mit einem regulären Ausdruck mit dem Flag g) wiederholt in einer Schleife aufrufen, um alle Treffer zu erhalten:
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.
Mit matchAll() können Sie auf die while-Schleife und exec mit g verzichten. Stattdessen erhalten Sie einen Iterator, den Sie mit den bequemeren Konstrukten for...of, Spread-Syntax für Arrays oder Array.from() verwenden können:
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 löst eine Ausnahme aus, wenn das Flag g fehlt.
const regexp = /[a-c]/;
const str = "abc";
str.matchAll(regexp);
// TypeError
matchAll erstellt intern eine Kopie von regexp. Anders als bei regexp.exec() ändert sich lastIndex daher beim Durchsuchen des Strings nicht.
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" ]
Das bedeutet allerdings auch, dass Sie lastIndex anders als bei der Verwendung von regexp.exec() in einer Schleife nicht verändern können, um den regulären Ausdruck vor- oder zurückzusetzen.
Besserer Zugriff auf Erfassungsgruppen (als mit String.prototype.match())
Ein weiterer wichtiger Grund für die Verwendung von matchAll ist der verbesserte Zugriff auf Erfassungsgruppen.
Bei Verwendung von match() mit dem globalen Flag g werden Erfassungsgruppen ignoriert:
const regexp = /t(e)(st(\d?))/g;
const str = "test1test2";
str.match(regexp); // ['test1', 'test2']
Mit matchAll können Sie einfach auf Erfassungsgruppen zugreifen:
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() mit einem Objekt verwenden, das [Symbol.matchAll]() implementiert und kein RegExp ist
Wenn ein Objekt eine Symbol.matchAll-Methode besitzt, kann es als benutzerdefinierter Matcher verwendet werden. Der Rückgabewert von Symbol.matchAll wird zum Rückgabewert von matchAll().
const str = "Hmm, this is interesting.";
str.matchAll({
[Symbol.matchAll](str) {
return [["Yes, it's interesting."]];
},
}); // returns [["Yes, it's interesting."]]
Spezifikationen
| Spezifikation |
|---|
| ECMAScript® 2027 Language Specification> # sec-string.prototype.matchall> |