Gruppen und Rückverweise

Gruppen gruppieren mehrere Muster als Ganzes, und erfassende Gruppen liefern zusätzliche Informationen zu Teilübereinstimmungen, wenn ein regulärer Ausdruck auf eine Zeichenkette angewendet wird. Rückverweise beziehen sich auf eine zuvor erfasste Gruppe im selben regulären Ausdruck.

Probieren Sie es aus

// Groups
const imageDescription = "This image has a resolution of 1440×900 pixels.";
const regexpSize = /(\d+)×(\d+)/;
const match = imageDescription.match(regexpSize);
console.log(`Width: ${match[1]} / Height: ${match[2]}.`);
// Expected output: "Width: 1440 / Height: 900."

// Backreferences
const findDuplicates = "foo foo bar";
const regex = /\b(\w+)\s+\1\b/g;
console.log(findDuplicates.match(regex));
// Expected output: Array ["foo foo"]

Typen

Zeichen Bedeutung
(x)

Erfassungsgruppe: Passt zu x und merkt sich die Übereinstimmung. Zum Beispiel passt /(foo)/ zu "foo" in "foo bar" und merkt es sich.

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

Erfassungsgruppen haben eine Leistungseinbuße. Wenn Sie das gematchte Teilstring nicht abrufen müssen, bevorzugen Sie nicht-erfassende Klammern (siehe unten).

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

(?<Name>x)

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

Um beispielsweise den US-amerikanischen Vorwahlbereich aus einer Telefonnummer zu extrahieren, könnten wir /\((?<area>\d\d\d)\)/ verwenden. Die resultierende Nummer würde unter matches.groups.area angezeigt.

(?:x)

Nicht-erfassende Gruppe: Passt zu "x", merkt sich aber nicht die Übereinstimmung. Der gematchte Teilstring kann nicht aus den Elementen des resultierenden Arrays ([1], …, [n]) oder über die vordefinierten Eigenschaften des RegExp-Objekts ($1, …, $9) abgerufen werden.

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

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

\n

Rückverweis: Dabei ist "n" eine positive ganze Zahl. Passt zu demselben Teilstring, der von der n-ten Erfassergruppe im regulären Ausdruck (gezählt von den linken Klammern) gematcht wurde. Zum Beispiel, /apple(,)\sorange\1/ passt zu "apple, orange," in "apple, orange, cherry, peach".

\k<Name>

Benannter Rückverweis: Ein Rückverweis auf das letzte Teilstring, das mit der Benannten Erfassergruppe übereinstimmt, angegeben durch <Name>.

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

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

Beispiele

Verwenden von Gruppen

In diesem Beispiel passen wir zwei Wörter in einem strukturierten Format an, indem wir erfassende Gruppen verwenden, um sie zu merken. \w+ passt zu einem oder mehreren 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]}`);
}

Weitere Beispiele finden Sie im Erfassergruppe-Referenz.

Verwenden benannter Gruppen

Dieses Beispiel ist dasselbe wie oben, aber wir verwenden benannte Erfassergruppen, um die gematchten Wörter zu merken. So können wir auf die gematchten Wörter anhand ihrer 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}`);
}

Weitere Beispiele finden Sie im benannte Erfassergruppe-Referenz.

Verwenden von Gruppen und Rückverweisen

In diesem Beispiel matchen wir zuerst ein einzelnes oder doppeltes Anführungszeichen mit ['"], merken es uns, matchen eine beliebige Anzahl von Zeichen mit .*? (*? ist ein nicht-gieriger Quantifizierer), bis wir das gematchte Anführungszeichen erneut mit \1 matchen. Das \1 ist ein Rückverweis auf die erste erfassende Gruppe, die denselbe 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]);
}

Weitere Beispiele finden Sie im Rückverweis-Referenz.

Verwenden von Gruppen und Match-Indizes

Durch Bereitstellung des d-Flags werden die Indizes jeder erfassenden Gruppe zurückgegeben. Dies ist besonders nützlich, wenn Sie jede gematchte Gruppe mit dem ursprünglichen Text korrelieren möchten — z.B. 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