Signatur
Beschreibung
Die Methode [Symbol.match]() enthält die eigentliche Suchlogik, die hinter String.prototype.match() steckt. Rufst du "text".match(regex) auf, gibt die String-Methode die Arbeit an regex[Symbol.match]("text") weiter. So legt der reguläre Ausdruck selbst fest, wie gesucht wird, und nicht der String.
Was herauskommt, hängt vom Flag g ab:
- Ohne
g: Die Methode verhält sich wieRegExp.prototype.exec(). Du bekommst den ersten Treffer als Array mit Capture-Gruppen und den Eigenschaftenindex,inputundgroups(bei gesetztemd-Flag zusätzlichindices). Gibt es keinen Treffer, kommtnullzurück. - Mit
g: Du bekommst ein Array mit allen gefundenen Teilstrings, aber ohne Capture-Gruppen. Gibt es keinen Treffer, kommtnullzurück. Vor der Suche wirdlastIndexauf0gesetzt.
Direkt aufrufen musst du die Methode selten. Wichtig ist sie vor allem, wenn du Unterklassen von RegExp schreibst und das Verhalten von match() ändern oder ergänzen willst. Außerdem prüfen Methoden wie String.prototype.startsWith(), endsWith() und includes() über die Eigenschaft Symbol.match, ob ein Argument als regulärer Ausdruck gilt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $str Pflicht | string | Der String, in dem gesucht wird. Andere Werte werden vorher in einen String umgewandelt. |
Rückgabewert
g-Flag: ein Treffer-Array wie bei exec() (mit index, input, groups). Mit g-Flag: ein Array aller gefundenen Teilstrings. Ohne Treffer in beiden Fällen: null.Beispiele
Direkter Aufruf statt String.prototype.match()
const re = /(\d{4})-(\d{2})/;
const text = 'Release: 2024-05';
// Beide Aufrufe liefern das gleiche Ergebnis
const a = text.match(re);
const b = re[Symbol.match](text);
console.log(a[0], a[1], a.index);
console.log(b[0] === a[0]);
Unterschied mit und ohne g-Flag
const text = 'Preise: 12 €, 7 €, 30 €';
console.log(/\d+/[Symbol.match](text)); // erster Treffer mit Details
console.log(/\d+/g[Symbol.match](text)); // alle Treffer, ohne Details
console.log(/xyz/g[Symbol.match](text)); // kein Treffer
RegExp-Unterklasse mit eigenem match-Verhalten
class SafeRegExp extends RegExp {
// Gibt statt null immer ein Array zurück
[Symbol.match](str) {
return super[Symbol.match](str) ?? [];
}
}
const tags = '#js #web #regex';
console.log(tags.match(new SafeRegExp('#\\w+', 'g')));
console.log('ohne Tags'.match(new SafeRegExp('#\\w+', 'g')).length);
Symbol.match abschalten, um RegExp als Text zu nutzen
const re = /foo/;
// Normalerweise wirft startsWith bei einer RegExp einen TypeError
try {
'/foo/bar'.startsWith(re);
} catch (e) {
console.log(e.constructor.name);
}
// Mit Symbol.match = false gilt das Objekt nicht mehr als RegExp
re[Symbol.match] = false;
console.log('/foo/bar'.startsWith(re)); // vergleicht mit String(re) = '/foo/'
// Wichtig · Fallstricke
- Keine Capture-Gruppen mit
g: Mit demg-Flag gehen Gruppen undindexverloren. Wenn du alle Treffer mit Details brauchst, nimmString.prototype.matchAll()bzw.RegExp.prototype[Symbol.matchAll](). lastIndexändert sich: Bei Ausdrücken mitgoderyverändert die MethodelastIndex. Wenn du dieselbe Instanz mehrfach verwendest, kann das zu unerwarteten Ergebnissen führen, vor allem mit demy-Flag ohneg.- Endlosschleifen: Kann das Muster eine leere Zeichenkette treffen (z. B.
/a*/g), rückt die Methode intern selbst weiter und liefert dabei auch leere Strings im Ergebnis-Array. - Eigene Implementierungen: Jedes Objekt mit einer Methode
[Symbol.match]kann anmatch()übergeben werden. Ob es als regulärer Ausdruck gilt, entscheidet dieselbe Eigenschaft (sieheIsRegExpin der Spezifikation). - Performance: Ein direkter Aufruf ist nicht schneller als
str.match(re). Er ist nur sinnvoll, wenn du Unterklassen schreibst oder etwas zur Laufzeit veränderst. - Kompatibilität: Wird von allen modernen Browsern und von Node.js ab Version 6 unterstützt, aber nicht vom Internet Explorer.