Bessere Übereinstimmungen mit String.prototype.matchAll()

Joe Medley
Joe Medley

In Chrome 73 wird die Methode String.prototype.matchAll() eingeführt. Das Verhalten ähnelt dem match(), gibt jedoch einen Listener mit allen Übereinstimmungen mit regulären Ausdrücken in einem globalen oder fixierten regulären Ausdruck zurück. Dies bietet eine einfache Möglichkeit, über Übereinstimmungen zu iterieren, insbesondere wenn Sie Zugriff zum Erfassen von Gruppen benötigen.

Was stimmt mit „match()“ nicht?

Die kurze Antwort lautet: nichts, es sei denn, Sie versuchen, globale Übereinstimmungen mit Erfassungsgruppen zurückzugeben. Hier ist ein Programmierrätsel für dich. Betrachten Sie den folgenden Code:

const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const results = string.match(regex);
console.log(results);
// → ['test1', 'test2']

Wenn Sie den Befehl in einer Konsole ausführen, werden Sie feststellen, dass ein Array mit den Strings 'test1' und 'test2' zurückgegeben wird. Wenn ich das Flag „g“ aus dem regulären Ausdruck entferne, enthält ich alle Erfassungsgruppen, erhalte aber nur die erste Übereinstimmung. Sie sieht so aus:

['test1', 'e', 'st1', '2', index: 0, input: 'test1test2', groups: undefined]

Dieser String enthält eine zweite mögliche Übereinstimmung, die mit 'test2' beginnt, ich habe jedoch keine gefunden. Hier ist das Rätsel: Wie erhalte ich alle Erfassungsgruppen für jedes Spiel? Die Erklärung für den Vorschlag String.prototype.matchAll() zeigt zwei mögliche Ansätze. Ich werde sie nicht beschreiben, weil Sie sie hoffentlich nicht mehr brauchen werden.

String.prototype.matchAll()

Wie würden die erklärenden Beispiele mit matchAll() aussehen? Schauen Sie nach.

const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const matches = string.matchAll(regex);
for (const match of matches) {
  console.log(match);
}

Hierzu gibt es einige Dinge zu beachten. Im Gegensatz zu match(), das bei einer globalen Suche ein Array zurückgibt, gibt matchAll() einen Iterator zurück, der mit for...of-Schleifen gut funktioniert. Der Iterator erzeugt ein Array für jede Übereinstimmung, einschließlich der Erfassungsgruppen mit einigen Extras. Wenn Sie diese in der Konsole ausgeben, sehen sie so aus:

['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', groups: undefined]
['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', groups: undefined]

Möglicherweise stellen Sie fest, dass der Wert für jede Übereinstimmung ein Array mit genau demselben Format ist, das von match() für nicht globale reguläre Ausdrücke zurückgegeben wird.

Bonus material

Das gilt vor allem für Personen, die mit regulären Ausdrücken noch nicht vertraut sind oder keine Experten. Möglicherweise haben Sie bemerkt, dass die Ergebnisse von „match()“ und „matchAll()“ (bei jedem Durchlauf) Arrays mit einigen zusätzlichen benannten Attributen sind. Bei der Vorbereitung dieses Artikels ist mir aufgefallen, dass diese Attribute einige Dokumentationsmängel auf MDN haben (habe ich bereits behoben). Hier ist eine kurze Beschreibung.

index
Der Index des ersten Ergebnisses im ursprünglichen String. Im obigen Beispiel beginnt test2 bei Position 5, daher hat index den Wert 5.
input
Der vollständige String, für den matchAll() ausgeführt wurde. In meinem Beispiel war das 'test1test2'.
groups
Enthält die Ergebnisse aller benannten Erfassungsgruppen, die im regulären Ausdruck angegeben sind.

Fazit

Falls ich etwas übersehen habe, kannst du es mir gern unten in den Kommentaren mitteilen. Informationen zu aktuellen Änderungen an JavaScript finden Sie in den vorherigen Updates oder auf der V8-Website.