Gruppen und Rückverweise

Gruppen fassen mehrere Muster als Ganzes zusammen, und erfassende Gruppen liefern zusätzliche Teilübereinstimmungsinformationen, wenn ein regulärer Ausdruck verwendet wird, um eine Zeichenkette zu überprüfen. 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 = /([0-9]+)×([0-9]+)/;
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)

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

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

Erfassende Gruppen haben einen Leistungseinbruch. Wenn Sie das erfasste Teilmuster nicht speichern müssen, sollten Sie bevorzugt nicht-erfassende Klammern verwenden (siehe unten).

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

(?<Name>x)

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

Zum Beispiel, um die Vorwahl 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: Passt zu "x", speichert die Übereinstimmung aber nicht. Das übereinstimmende Teilmuster kann weder aus den Elementen des Ergebnisarrays ([1], …, [n]) noch aus den vordefinierten Eigenschaften des Objekts RegExp ($1, …, $9) abgerufen werden.

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

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

\n

Rückverweis: Dabei ist "n" eine positive ganze Zahl. Passt zum gleichen Teilstring wie die n-te erfassende Gruppe im regulären Ausdruck (zählt die linken Klammern). Zum Beispiel passt /apple(,)\sorange\1/ zu "apple, orange," in "apple, orange, cherry, peach".

\k<Name>

Benannter Rückverweis: Ein Rückverweis auf den zuletzt mit der benannten erfassenden Gruppe übereinstimmenden Teilstring, der mit <Name> angegeben wurde.

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 Beginn eines Rückverweises auf eine benannte erfassende Gruppe anzuzeigen.

Beispiele

Verwendung von Gruppen

In diesem Beispiel werden zwei Wörter in einem strukturierten Format durch Verwendung von erfassenden Gruppen zusammengeführt. \w+ passt zu einem oder mehreren 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]}`);
}

Weitere Beispiele finden Sie in der Referenz zur erfassenden Gruppe.

Verwendung von benannten Gruppen

Dieses Beispiel ist dasselbe wie oben, aber wir verwenden benannte erfassende Gruppen, um die passenden Wörter anhand ihrer Bedeutung zugänglich zu machen.

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 in der Referenz zur benannten erfassenden Gruppe.

Verwendung von Gruppen und Rückverweisen

In diesem Beispiel wird zuerst ein einzelnes oder doppeltes Anführungszeichen mit ['"] abgeglichen, es wird gespeichert, eine beliebige Anzahl von Zeichen mit .*? abgeglichen (*? ist ein nicht-gieriger Quantor), bis das gespeicherte Anführungszeichen erneut mit \1 abgeglichen wird. Das \1 ist ein Rückverweis auf die erste erfassende Gruppe, der den gleichen Typ von Anführungszeichen abgleicht. 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 in der Referenz zum Rückverweis.

Verwendung von Gruppen und Übereinstimmungsindizes

Durch Angabe 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 abgleichen möchten – 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