Gruppen und Rückverweise

Gruppen fassen mehrere Muster zusammen, und erfassende Gruppen bieten zusätzliche Submatch-Informationen, wenn ein Regulärer Ausdruck verwendet wird, um gegen einen String zu matchen. Rückverweise beziehen sich auf eine zuvor erfasste Gruppe im selben Regulären Ausdruck.

Probieren Sie es aus

Typen

Zeichen Bedeutung
(x)

Erfassende Gruppe: Matcht x und speichert das Match. Zum Beispiel, /(foo)/ matcht und speichert "foo" in "foo bar".

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

Erfassende Gruppen haben einen Leistungseinbruch. Wenn Sie den gematchten Substring nicht zurückrufen müssen, bevorzugen Sie nicht-erfassende Klammern (siehe unten).

String.prototype.match() wird keine Gruppen zurückgeben, wenn das /.../g-Flag gesetzt ist. Sie können jedoch weiterhin String.prototype.matchAll() verwenden, um alle Matches zu erhalten.

(?<Name>x)

Benannte erfassende Gruppe: Matcht "x" und speichert es in der Eigenschaft `groups` der zurückgegebenen Matches unter dem Namen, der durch <Name> angegeben ist. Die spitzen Klammern (< und >) sind erforderlich für den Gruppennamen.

Um zum Beispiel den Vorwahlbereich der Vereinigten Staaten 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: Matcht "x" aber speichert das Match nicht. Der gematchte Substring kann nicht aus den Elementen des resultierenden Arrays ([1], …, [n]) oder von den vordefinierten Eigenschaften des RegExp-Objekts ($1, …, $9) zurückgerufen werden.

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

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

\n

Rückverweis: Wo "n" eine positive Ganzzahl ist. Matcht denselben Substring, der von der n-ten erfassenden Gruppe im Regulären Ausdruck gematcht wurde (zählend nach links stehenden Klammern). Zum Beispiel, /apple(,)\sorange\1/ matcht "apple, orange," in "apple, orange, cherry, peach".

\k<Name>

Benannter Rückverweis: Ein Rückverweis auf den letzten Substring, der der Benannten erfassenden Gruppe entspricht, die durch <Name> angegeben ist.

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

Hinweis: \k wird hier wörtlich verwendet, um den Beginn eines Rückverweises auf eine Benannte erfassende Gruppe zu kennzeichnen.

Beispiele

Verwendung von Gruppen

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

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]}`);
}

Sehen Sie mehr Beispiele in der Erfassende Gruppe Referenz.

Verwendung von benannten Gruppen

Dieses Beispiel ist dasselbe wie oben, aber wir verwenden benannte erfassende Gruppen, um die gematchten Wörter stattdessen zu speichern. Auf diese Weise können wir auf die gematchten Wörter durch ihre Bedeutung zugreifen.

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}`);
}

Sehen Sie mehr Beispiele in der Benannte erfassende Gruppe Referenz.

Verwendung von Gruppen und Rückverweisen

In diesem Beispiel matchen wir zuerst ein einzelnes oder doppeltes Anführungszeichen mit ['"], speichern es, matchen eine beliebige Anzahl von Zeichen mit .*? (*? ist ein nicht-gieriger Quantor), bis wir das gespeicherte Anführungszeichen erneut mit \1 matchen. Das \1 ist ein Rückverweis auf die erste erfassende Gruppe, welche denselben Typ von Anführungszeichen matcht. Das Ergebnis sind daher zwei Strings: "'" und '"'.

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

Sehen Sie mehr Beispiele in der Rückverweis Referenz.

Verwendung von Gruppen und Match-Indizes

Indem das d-Flag bereitgestellt wird, werden die Indizes jeder erfassenden Gruppe zurückgegeben. Dies ist besonders nützlich, wenn Sie jede gematchte Gruppe mit dem Originaltext in Beziehung setzen möchten – zum Beispiel, um Compilerdiagnosen bereitzustellen.

js
const code = `function add(x, y) {
  return x + y;
}`;
const functionRegexp =
  /(function\s+)(?<name>[$_\p{ID_Start}][$\u200c\u200d\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