Start · Sprachen · JavaScript · Referenz · Rückverweis: \\1, \\2

Rückverweis: \\1, \\2

Keyword

Ein Rückverweis <code>\N</code> passt im regulären Ausdruck genau auf den Text, den die N-te erfassende Gruppe zuvor gefunden hat.

seit JavaScript ES3 (Baseline: alle Browser) Kategorie: syntax

Signatur

/(…)\N/ – z. B. \1, \2, …, \99

Beschreibung

Ein Rückverweis (englisch: backreference) wie \1 oder \2 verweist auf den Teilstring, den eine erfassende Gruppe (…) im selben Muster gefunden hat. Er passt nicht auf das Muster der Gruppe, sondern auf den konkret gefundenen Text. /(\w)\1/ findet also zwei gleiche Zeichen hintereinander wie "aa", aber nicht "ab".

Die Gruppen werden von links nach rechts nach ihrer öffnenden Klammer nummeriert, beginnend bei 1. Nicht erfassende Gruppen (?:…) und Lookarounds zählen nicht mit. Benannte Gruppen (?<name>…) bekommen trotzdem eine Nummer und lassen sich mit \N oder besser lesbar mit \k<name> ansprechen.

Typische Einsatzfälle sind doppelte Wörter, zueinander passende Anführungszeichen oder Tags, wiederholte Zeichen und symmetrische Trennzeichen wie 2024-01-01 und 2024/01/01, bei denen beide Trenner gleich sein müssen.

Wichtig: \1 gilt nur innerhalb des Musters. In Ersetzungszeichenketten von String.prototype.replace() verwendet man stattdessen $1 bzw. $<name>.

Parameter

Name Typ Default Beschreibung
$N Pflicht number (positive Ganzzahl, dezimal) Nummer der erfassenden Gruppe (ab 1). Mit dem Flag u oder v muss die Gruppe im Muster existieren, sonst gibt es einen SyntaxError.

Rückgabewert

Typ
— (Musterbestandteil)
Beschreibung
Kein Rückgabewert im engeren Sinn: Der Rückverweis passt auf genau die Zeichenfolge, die Gruppe N gefunden hat. Hat die Gruppe an keinem Treffer teilgenommen, passt er auf den leeren String, die Suche scheitert also nicht.

Beispiele

Doppelte Wörter finden und entfernen

const text = "Das ist ist ein Test Test.";
const doppelt = /\b(\w+)\s+\1\b/gi;

console.log(text.match(doppelt));
// Ersetzen: in der Ersetzung $1 statt \1
console.log(text.replace(doppelt, "$1"));
["ist ist", "Test Test"] "Das ist ein Test."

Passende Anführungszeichen erkennen

const satz = `Er sagte "Hallo" und 'Tschüss'.`;
const zitate = /(['"])(.*?)\1/g;

const inhalte = [...satz.matchAll(zitate)].map(m => m[2]);
console.log(inhalte);
["Hallo", "Tschüss"]

Wiederholte Zeichen und gleiche Trenner

console.log("aaabbcddd".match(/(.)\1+/g));

const datum = /^\d{4}([-\/.])\d{2}\1\d{2}$/;
console.log(datum.test("2024-05-17")); // gleicher Trenner
console.log(datum.test("2024-05/17")); // gemischt
["aaa", "bb", "ddd"] true false

HTML-Tag-Paare mit benanntem Rückverweis

const html = "<b>fett</b> <i>kursiv</b>";
const paar = /<(?<tag>\w+)>(.*?)<\/\k<tag>>/g;

for (const m of html.matchAll(paar)) {
  console.log(m.groups.tag, "→", m[2]);
}
b → fett

Randfälle: nicht beteiligte Gruppe und Flag i

// Gruppe nimmt nicht teil → \1 passt auf ""
console.log(/(a)?b\1/.test("b"));

// Mit i wird auch ohne Beachtung der Groß-/Kleinschreibung verglichen
console.log(/(ab)\1/i.test("abAB"));

// Ohne u: \2 ist hier ein Oktal-Escape (U+0002), mit u ein Fehler
try { new RegExp("(a)\\2", "u"); } catch (e) { console.log(e.name); }
true true SyntaxError

// Wichtig · Fallstricke

  • Nicht vorhandene Gruppe: Ohne Flag u/v wird \N für eine nicht existierende Gruppe aus Kompatibilitätsgründen als Oktal-Escape (z. B. \2 → U+0002) oder bei \8/\9 als Ziffer gelesen. Das ist eine häufige, schwer zu findende Fehlerquelle. Mit u/v gibt es dagegen einen SyntaxError.
  • In Zeichenklassen ist [\1] kein Rückverweis, sondern ohne u ein Oktal-Escape und mit u ein Fehler.
  • Vorwärtsverweise wie /\1(a)/ und Verweise auf die eigene Gruppe wie /(a\1)/ passen immer auf den leeren String.
  • Quantifizierte Gruppen: Bei /(\w)+\1/ bezieht sich \1 auf die letzte Wiederholung der Gruppe. Innere Gruppen werden bei jeder Wiederholung zurückgesetzt.
  • Lookbehind (?<=…) wird von rechts nach links ausgewertet. Dort muss der Rückverweis links von seiner Gruppe stehen, z. B. /(?<=\1(a))b/.
  • Zweistellige Nummern: \10 ist nur dann ein Rückverweis auf Gruppe 10, wenn es mindestens 10 Gruppen gibt. Bei vielen Gruppen sind benannte Rückverweise (\k<name>) deutlich besser zu warten.
  • Performance: Rückverweise können Backtracking verstärken. Bei Muster aus Nutzereingaben besteht ReDoS-Gefahr.
  • Im RegExp-Konstruktor muss der Backslash doppelt geschrieben werden: new RegExp("(\\w)\\1").