Gruppen und Rückverweise

Gruppen fassen mehrere Muster als Ganzes zusammen, und erfassende Gruppen bieten zusätzliche Teilübereinstimmungsinformationen, wenn ein regulärer Ausdruck verwendet wird, um mit einem String übereinzustimmen. Rückverweise beziehen sich auf eine zuvor erfasste Gruppe im gleichen regulären Ausdruck.

Probieren Sie es aus

Typen

Zeichen Bedeutung
(x)

Erfassende Gruppe: Passt auf x und merkt sich die Übereinstimmung. Zum Beispiel passt /(foo)/ und merkt sich "foo" in "foo bar".

Ein regulärer Ausdruck kann mehrere erfassende Gruppen haben. In den Ergebnissen befinden sich Übereinstimmungen mit erfassenden Gruppen typischerweise in einem Array, dessen Mitglieder in der gleichen Reihenfolge sind wie die linken Klammern in der erfassenden Gruppe. Dies ist normalerweise einfach die Reihenfolge der erfassenden Gruppen selbst. Dies wird wichtig, wenn erfassende Gruppen verschachtelt sind. Übereinstimmungen werden über den Index der Elemente des Ergebnisses ([1], …, [n]) oder über die vordefinierten Eigenschaften des RegExp-Objekts ($1, …, $9) abgerufen.

Erfassende Gruppen haben ein Leistungseinbuße. Wenn Sie den übereinstimmenden Teilstring nicht zurückrufen müssen, bevorzugen Sie nicht-erfassende Klammern (siehe unten).

String.prototype.match() gibt keine Gruppen zurück, wenn der /.../g-Flag gesetzt ist. Sie können jedoch weiterhin String.prototype.matchAll() verwenden, um alle Übereinstimmungen zu erhalten.

(?<Name>x)

Benannte erfassende Gruppe: Passt auf "x" und speichert es in der Eigenschaft "groups" der zurückgegebenen Übereinstimmungen unter dem durch <Name> angegebenen Namen. Die spitzen Klammern (< und >) sind für den Gruppennamen erforderlich.

Zum Beispiel, um die US-Vorwahl aus einer Telefonnummer zu extrahieren, könnten wir /\((?<area>\d\d\d)\)/ verwenden. Die resultierende Nummer würde unter matches.groups.area erscheinen.

(?:x)

Nicht-erfassende Gruppe: Passt auf "x", merkt sich jedoch die Übereinstimmung nicht. Der übereinstimmende Teilstring kann weder von den Elementen des resultierenden Arrays ([1], …, [n]) noch von den vordefinierten Eigenschaften des RegExp-Objekts ($1, …, $9) zurückgerufen werden.

(?flags:x), (?:flags-flags:x)

Modifizierer: Aktiviert oder deaktiviert die angegebenen Flags nur für das eingeschlossene Muster. Nur die Flags i, m und s können in einem Modifizierer verwendet werden.

\n

Rückverweis: Wo "n" eine positive ganze Zahl ist. Passt auf den gleichen Teilstring, der durch die n-te erfassende Gruppe im regulären Ausdruck erfasst wurde (linke Klammern zählend). Zum Beispiel, /apple(,)\sorange\1/ passt auf "apple, orange," in "apple, orange, cherry, peach".

\k<Name>

Benannter Rückverweis: Ein Rückverweis auf den letzten Teilstring, der mit der benannten erfassenden Gruppe übereinstimmt, die durch <Name> angegeben ist.

Zum Beispiel, /(?<title>\w+), yes \k<title>/ passt auf "Sir, yes Sir" in "Do you copy? Sir, yes Sir!".

Hinweis: \k wird hier buchstäblich verwendet, um den Beginn eines Rückverweises auf eine benannte erfassende Gruppe anzuzeigen.

Beispiele

Gruppen verwenden

In diesem Beispiel vergleichen wir zwei Wörter in einem strukturierten Format, indem wir erfassende Gruppen verwenden, um sie zu merken. \w+ passt auf ein oder mehrere Wortzeichen, und die Klammern () erstellen eine erfassende Gruppe. Das g-Flag wird verwendet, um alle Vorkommen zu erfassen.

js
const personList = `First_Name: John, Last_Name: Doe
First_Name: Jane, Last_Name: Smith`;

const regexpNames = /First_Name: (\w+), Last_Name: (\w+)/g;
for (const match of personList.matchAll(regexpNames)) {
  console.log(`Hello ${match[1]} ${match[2]}`);
}

Siehe weitere Beispiele in der erfassenden Gruppe-Referenz.

Benannte Gruppen verwenden

Dieses Beispiel ist dasselbe wie oben, aber wir verwenden benannte erfassende Gruppen, um die übereinstimmenden Wörter stattdessen zu merken. Auf diese Weise können wir die übereinstimmenden Wörter nach ihrer Bedeutung abrufen.

js
const personList = `First_Name: John, Last_Name: Doe
First_Name: Jane, Last_Name: Smith`;

const regexpNames =
  /First_Name: (?<firstName>\w+), Last_Name: (?<lastName>\w+)/g;
for (const match of personList.matchAll(regexpNames)) {
  console.log(`Hello ${match.groups.firstName} ${match.groups.lastName}`);
}

Siehe weitere Beispiele in der benannten erfassenden Gruppe-Referenz.

Gruppen und Rückverweise verwenden

In diesem Beispiel erfassen wir zuerst ein einfaches oder doppeltes Anführungszeichen mit ['"], merken es uns, erfassen eine beliebige Anzahl von Zeichen mit .*? (*? ist ein nicht gieriger Quantifizierer), bis wir das gemerkte Anführungszeichen mit \1 erneut erfassen. Das \1 ist ein Rückverweis auf die erste erfassende Gruppe, die auf denselben Typ von Anführungszeichen passt. Das Ergebnis wird daher zwei Strings sein: "'" und '"'.

js
const quote = `Single quote "'" and double quote '"'`;
const regexpQuotes = /(['"]).*?\1/g;
for (const match of quote.matchAll(regexpQuotes)) {
  console.log(match[0]);
}

Siehe weitere Beispiele in der Rückverweis-Referenz.

Gruppen und Übereinstimmungsindizes verwenden

Durch Bereitstellung des d-Flags werden die Indizes jeder erfassenden Gruppe zurückgegeben. Dies ist besonders nützlich, wenn Sie jede erfasste Gruppe mit dem ursprünglichen Text korrelieren – beispielsweise, um Compiler-Diagnosen bereitzustellen.

js
const code = `function add(x, y) {
  return x + y;
}`;
const functionRegexp =
  /(function\s+)(?<name>[$_\p{ID_Start}][$\p{ID_Continue}]*)/du;
const match = functionRegexp.exec(code);
const lines = code.split("\n");
lines.splice(
  1,
  0,
  " ".repeat(match.indices[1][1] - match.indices[1][0]) +
    "^".repeat(match.indices.groups.name[1] - match.indices.groups.name[0]),
);
console.log(lines.join("\n"));
// function add(x, y) {
//          ^^^
//   return x + y;
// }

Siehe auch