RegExp.prototype[Symbol.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 [Symbol.matchAll]() von RegExp-Instanzen legt fest, wie String.prototype.matchAll sich verhalten soll.
Probieren Sie es aus
class MyRegExp extends RegExp {
[Symbol.matchAll](str) {
const result = RegExp.prototype[Symbol.matchAll].call(this, str);
if (!result) {
return null;
}
return Array.from(result);
}
}
const re = new MyRegExp("-\\d+", "g");
console.log("2016-01-02|2019-03-07".matchAll(re));
// Expected output: Array [Array ["-01"], Array ["-02"], Array ["-03"], Array ["-07"]]
Syntax
regexp[Symbol.matchAll](str)
Parameter
Rückgabewert
Ein iterierbares Iterator-Objekt (das nicht neu gestartet werden kann) von Übereinstimmungen. Jede Übereinstimmung ist ein Array mit derselben Struktur wie der Rückgabewert von RegExp.prototype.exec().
Beschreibung
Diese Methode existiert, um das Verhalten von matchAll() in Unterklassen von RegExp anzupassen. Sie wird intern in String.prototype.matchAll() aufgerufen. Beispielsweise liefern die folgenden zwei Beispiele dasselbe Ergebnis.
"abc".matchAll(/a/g);
/a/g[Symbol.matchAll]("abc");
Ähnlich wie [Symbol.split]() beginnt [Symbol.matchAll]() damit, [Symbol.species] zu verwenden, um ein neues Regex zu erstellen, wodurch vermieden wird, dass das originale RegExp in irgendeiner Weise verändert wird. Der Konstruktor erhält this und die ursprünglichen Flags. lastIndex beginnt mit dem Wert des ursprünglichen Regex.
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" ]
Wenn das Regex global ist (mit dem g-Flag), wird jedes Mal, wenn die next()-Methode des zurückgegebenen Iterators aufgerufen wird, das RegExp's exec() aufgerufen und das Ergebnis wird zurückgegeben. Wenn die aktuelle Übereinstimmung ein leerer String ist, wird der lastIndex dennoch weitergeschaltet. Wenn das Regex das u-Flag besitzt, schreitet es um einen Unicode-Codepunkt voran; andernfalls schreitet es um einen UTF-16-Codepunkt voran.
console.log(Array.from("😄".matchAll(/(?:)/g)));
// [ [ "" ], [ "" ], [ "" ] ]
console.log(Array.from("😄".matchAll(/(?:)/gu)));
// [ [ "" ], [ "" ] ]
Wenn das Regex nicht global ist, gibt der zurückgegebene Iterator einmal das exec()-Ergebnis zurück und beendet dann. (Die Validierung, dass der Input ein globales Regex ist, erfolgt in String.prototype.matchAll(). [Symbol.matchAll]() validiert die Flags von this nicht.)
Wenn das Regex sticky und global ist, wird es trotzdem sticky Abgleiche durchführen — d.h. es wird keine Vorkommen jenseits des lastIndex abgleichen.
console.log(Array.from("ab-c".matchAll(/[abc]/gy)));
// [ [ "a" ], [ "b" ] ]
Beispiele
>Direkter Aufruf
Diese Methode kann fast auf dieselbe Weise wie String.prototype.matchAll() verwendet werden, abgesehen vom unterschiedlichen Wert von this und der unterschiedlichen Reihenfolge der Argumente.
const re = /\d+/g;
const str = "2016-01-02";
const result = re[Symbol.matchAll](str);
console.log(Array.from(result, (x) => x[0]));
// [ "2016", "01", "02" ]
Verwendung von [Symbol.matchAll]() in Unterklassen
Unterklassen von RegExp können die Methode [Symbol.matchAll]() überschreiben, um das Standardverhalten zu ändern.
Zum Beispiel, um ein Array statt eines Iterators zurückzugeben:
class MyRegExp extends RegExp {
[Symbol.matchAll](str) {
const result = RegExp.prototype[Symbol.matchAll].call(this, str);
return result ? Array.from(result) : null;
}
}
const re = new MyRegExp("(\\d+)-(\\d+)-(\\d+)", "g");
const str = "2016-01-02|2019-03-07";
const result = str.matchAll(re);
console.log(result[0]);
// [ "2016-01-02", "2016", "01", "02" ]
console.log(result[1]);
// [ "2019-03-07", "2019", "03", "07" ]
Spezifikationen
| Spezifikation |
|---|
| ECMAScript® 2027 Language Specification> # sec-regexp-prototype-%symbol.matchall%> |