Start · Sprachen · JavaScript · Referenz · RegExp.prototype[Symbol.matchAll]()

RegExp.prototype[Symbol.matchAll]()

Methode

Gibt einen Iterator über alle Treffer des regulären Ausdrucks in <code>str</code> zurück und legt fest, wie <code>String.prototype.matchAll()</code> arbeitet.

seit JavaScript ES2020 Kategorie: method-property

Signatur

RegExp.prototype[Symbol.matchAll](str)

Beschreibung

Die Methode [Symbol.matchAll]() ist der interne Mechanismus hinter String.prototype.matchAll(). Bei einem Aufruf wie str.matchAll(regexp) sucht die Engine auf dem Argument nach einer Methode unter dem Schlüssel Symbol.matchAll und ruft diese mit dem String auf. Bei RegExp-Objekten ist das genau diese Methode.

Intern passiert Folgendes: Aus dem regulären Ausdruck wird über den Species-Konstruktor (RegExp[Symbol.species]) eine Kopie mit denselben Flags erzeugt. Ihr lastIndex wird auf den aktuellen lastIndex des Originals gesetzt. Zurück kommt ein RegExp String Iterator, der die Treffer erst beim Weiterschalten (also „lazy“) nacheinander liefert. Jeder Treffer ist ein Array wie bei RegExp.prototype.exec(), also mit den Eigenschaften index, input, groups und, falls das Flag d gesetzt ist, auch indices. Weil nur die Kopie verändert wird, bleibt der lastIndex des ursprünglichen Ausdrucks unverändert.

Direkt aufrufen muss man die Methode selten. Wichtig ist sie vor allem, wenn man RegExp ableitet und das Verhalten von matchAll() anpassen will, zum Beispiel um ein Array statt eines Iterators zurückzugeben oder Treffer zu filtern. Auch eigene Objekte, die keine regulären Ausdrücke sind, können Symbol.matchAll umsetzen und damit an String.prototype.matchAll() übergeben werden.

Parameter

Name Typ Default Beschreibung
$str Pflicht string Der String, in dem gesucht wird. Werte, die kein String sind, werden mit String() umgewandelt.

Rückgabewert

Typ
Iterator<RegExpExecArray>
Beschreibung
Ein iterierbarer RegExp String Iterator. Jeder Schritt liefert ein Treffer-Array wie exec(). Gibt es keine Treffer, ist der Iterator sofort erschöpft. Ohne Flag g liefert er höchstens einen Treffer.

Beispiele

Direkter Aufruf: alle Zahlen aus einem Datum holen

const re = /[0-9]+/g;
const str = '2016-01-02';

const iterator = re[Symbol.matchAll](str);
console.log(Array.from(iterator, (m) => m[0]));
[ '2016', '01', '02' ]

Unterklasse: matchAll() gibt ein Array statt eines Iterators zurück

class ArrayMatchRegExp extends RegExp {
  [Symbol.matchAll](str) {
    const iterator = RegExp.prototype[Symbol.matchAll].call(this, str);
    return Array.from(iterator);
  }
}

const re = new ArrayMatchRegExp('(?<jahr>\\d{4})-(?<monat>\\d{2})', 'g');
const text = 'Release 2023-05, Update 2024-11';

const treffer = text.matchAll(re); // ruft re[Symbol.matchAll] auf
console.log(Array.isArray(treffer));
console.log(treffer.map((m) => `${m.groups.monat}/${m.groups.jahr}`));
true [ '05/2023', '11/2024' ]

lastIndex wird übernommen, das Original bleibt unverändert

const re = /a/g;
re.lastIndex = 2;

const positionen = [...re[Symbol.matchAll]('aaaa')].map((m) => m.index);
console.log(positionen);    // Suche beginnt bei Index 2
console.log(re.lastIndex);  // Original unverändert
[ 2, 3 ] 2

Ohne g-Flag: direkter Aufruf liefert nur einen Treffer

const re = /\d+/; // kein g-Flag

console.log([...re[Symbol.matchAll]('1 2 3')].map((m) => m[0]));

try {
  '1 2 3'.matchAll(re);
} catch (err) {
  console.log(err.constructor.name);
}
[ '1' ] TypeError

// Wichtig · Fallstricke

  • g-Flag: String.prototype.matchAll() wirft einen TypeError, wenn ein RegExp ohne Flag g übergeben wird. Das passiert, bevor [Symbol.matchAll] aufgerufen wird. Ruft man die Methode direkt auf, gibt es keinen Fehler, aber der Iterator liefert nur den ersten Treffer.
  • Lazy und nur einmal nutzbar: Der Iterator sucht erst beim Weiterschalten und ist danach erschöpft. Wer die Treffer mehrfach braucht, wandelt sie mit Array.from() oder dem Spread-Operator um.
  • Leere Treffer: Bei Mustern, die leere Treffer finden können (z. B. /x*/g), wird lastIndex automatisch weitergeschoben, damit keine Endlosschleife entsteht. Mit Flag u oder v geschieht das nach Unicode-Codepoints.
  • Species: Die interne Kopie wird über this.constructor[Symbol.species] erzeugt. Überschreibt eine Unterklasse Symbol.species, beeinflusst das den verwendeten Matcher.
  • Kompatibilität: Ab ES2020, in allen modernen Browsern und ab Node.js 12 verfügbar. Nicht im Internet Explorer.