Regex: Sticky-Flag „y", Suche an einer bestimmten Position
Das Sticky-Flag (y) in regulären Ausdrücken verankert jede Suche an einer exakten Position (lastIndex) und ermöglicht sequenzielles Parsen ohne Lücken.
Das Flag y — das Sticky-Flag — ist eines der Flags, die man einem JavaScript-regulären Ausdruck hinzufügen kann. Es verankert jede Suche an genau einer Position: dem lastIndex des regulären Ausdrucks. Wenn ein Treffer nicht genau an lastIndex beginnen kann, schlägt die Suche fehl — die Engine scannt nicht weiter vorwärts, um anderswo einen Treffer zu finden.
Diese Seite erklärt, was das Sticky-Flag bewirkt, wie es sich vom globalen Flag (g) unterscheidet, wie lastIndex gelesen und aktualisiert wird, welche häufigen Fallstricke es gibt und wo das Flag wirklich sinnvoll eingesetzt wird (Tokenizer und sequenzielle Parser).
Das Konzept des Sticky-Flags (y)
Das Sticky-Flag (y) stellt sicher, dass der Treffer genau an dem Index beginnt, der in der lastIndex-Eigenschaft des Regex-Objekts gespeichert ist. Dies ist der wesentliche Unterschied zum globalen Flag (g): g erlaubt der Engine, von lastIndex aus vorwärts zu scannen und den nächsten Treffer an einer beliebigen späteren Stelle im string zu finden, während y verlangt, dass der Treffer bei lastIndex beginnt — oder gar nicht. Dieses „kein Vorwärtsscannen"-Verhalten ist genau das, was ein Tokenizer benötigt — es stellt sicher, dass die Eingabe lückenlos verarbeitet wird, ohne unerwartete Lücken zwischen den Tokens.
y scannt nicht vorwärts — g schon
Am deutlichsten sieht man den Unterschied, wenn man beiden Flags ein Muster gibt, das an Position 0 nicht übereinstimmt:
Das Flag g findet abc, obwohl es erst an Index 3 beginnt. Das Flag y gibt null zurück, weil an Position 0 ein . steht, nicht der Anfang von abc.
Im obigen Beispiel stellt das Flag y sicher, dass der zweite test-Aufruf genau dort mit dem Abgleichen beginnt, wo der vorherige Treffer aufgehört hat. Zwei Details sind dabei bemerkenswert:
- Ein erfolgreicher Treffer rückt
lastIndexvor auf den Index unmittelbar nach dem Treffer (0 → 3 → 6). Dieses automatische Vorrücken ermöglicht es,test/execin einer Schleife aufzurufen. - Ein fehlgeschlagener Treffer setzt
lastIndexauf 0 zurück. Nachdem der dritte Aufruffalsezurückgibt, stehtlastIndexwieder bei 0 und ist bereit, von vorne zu beginnen.
lastIndex wird gelesen und geschrieben
lastIndex ist nicht nur eine Eingabe, die man setzt — die Engine aktualisiert ihn bei jedem test/exec-Aufruf, der y (oder g) verwendet. Das übliche Muster ist daher: lastIndex einmal setzen, wenn man an einer anderen Stelle als 0 beginnen möchte, und dann die Schleife selbst damit umgehen lassen.
Sticky beeinflusst auch Anker
Mit dem Flag y wird der Zeilenanfangs-Anker ^ nicht neu auf lastIndex verankert — ^ bedeutet weiterhin „Anfang des gesamten Strings" (oder Zeilenanfang mit dem Flag m). Das Sticky-Verhalten kommt von der impliziten Regel „Treffer bei lastIndex", nicht davon, dass ^ umgeschrieben wird. Ein Muster wie /^x/y schlägt daher bei jedem lastIndex größer als 0 fehl, weil ^ dort niemals erfüllt werden kann.
Praktische Anwendungen des Sticky-Flags
Parsen von Datenströmen
Das Sticky-Flag ist besonders vorteilhaft beim Parsen von Datenströmen, bei denen Tokens sequenziell abgeglichen werden müssen.
Tokenisierung von Strings
Ein weiterer häufiger Anwendungsfall ist die Tokenisierung von Strings, bei der sichergestellt werden muss, dass der Tokenizer von einem Treffer zum nächsten übergeht, ohne Zeichen zu überspringen.
Suche an einer bestimmten Position
Die lastIndex-Eigenschaft von JavaScript in Kombination mit dem Sticky-Flag kann verwendet werden, um nach Mustern ab einer bestimmten Position in einem string zu suchen.
In diesem Beispiel ermöglicht das Setzen von lastIndex auf 6, dass die Methode test das Wort „world" ab der angegebenen Position findet.
Kombination des Sticky-Flags mit anderen Flags
Das Sticky-Flag kann mit anderen Flags wie g (global) kombiniert werden, um die Musterabgleich-Fähigkeiten zu erweitern. In diesem Beispiel ermöglicht das Flag g eine globale Suche im gesamten string, während das Flag y sicherstellt, dass jeder Treffer genau an der lastIndex-Position beginnt. Diese Kombination erlaubt eine globale Suche mit dem strikten sequenziellen Abgleichverhalten des Sticky-Flags.
In diesem Beispiel wurde der reguläre Ausdruck so angepasst, dass er das Komma-Trennzeichen mitverbraucht. Dadurch beginnt der nächste Treffer an der richtigen Position, ohne manuelle Index-Manipulation.
Fortgeschrittene Beispiele
Extrahieren von Schlüssel-Wert-Paaren
Betrachten wir ein komplexeres Szenario, bei dem Schlüssel-Wert-Paare aus einem string mit verschiedenen Trennzeichen extrahiert werden müssen. Jeder Teil des Paares wird mit einer Erfassungsgruppe herausgezogen — match[1] ist der Schlüssel und match[3] ist der Wert.
Parsen von Logs
Das Sticky-Flag kann beim Parsen strukturierter Logs äußerst nützlich sein, bei denen Einträge ab bestimmten Positionen abgeglichen werden müssen.
Beachten Sie, dass die Nachrichtengruppe [^;]+ ist („alles bis zum nächsten ;") und nicht \w+. Mit \w+ würde eine Nachricht, die ein Leerzeichen enthält, den Treffer mittendrin abbrechen; da das Sticky-Flag das Überspringen verweigert, würde der nächste exec-Aufruf fehlschlagen und die Schleife vorzeitig beenden — wobei die verbleibenden Einträge lautlos verworfen würden. Dies ist der häufigste Fallstrick beim Sticky-Flag: Das Muster muss die Eingabe lückenlos verbrauchen, sonst bricht das Parsen abrupt ab.
Wann y verwenden (und wann nicht)
Greifen Sie zum Sticky-Flag, wenn:
- Sie einen Tokenizer oder Parser schreiben und die Eingabe lückenlos, ein Token nach dem anderen, ohne Lücken verbrauchen müssen.
- Sie testen möchten, ob ein Muster an genau einer bestimmten Position übereinstimmt, ohne dass die Engine weiter im string nach einem Treffer sucht.
Bevorzugen Sie das einfache globale Flag (g), wenn Sie schlicht alle Treffer an beliebigen Stellen im string suchen und es keine Rolle spielt, ob sie benachbart sind — beispielsweise beim Suchen aller E-Mail-Adressen in einem Dokument.
Denken Sie an die zwei Regeln, die die meisten Sticky-Flag-Bugs verursachen: Ein fehlgeschlagener Treffer setzt lastIndex auf 0 zurück, und Ihr Muster muss jedes Zeichen zwischen den Treffern verbrauchen, sonst endet die Schleife zu früh.
Fazit
Das Sticky-Flag (y) tauscht den „überall suchen"-Komfort von g gegen ein striktes, positionsgebundenes Abgleichen bei lastIndex ein. Dieser Kompromiss ist genau das, was man beim Erstellen von Tokenizern und sequenziellen Parsern möchte, bei denen lückenlose Verarbeitung wichtig ist. Kombinieren Sie es mit Erfassungsgruppen, um strukturierte Daten zu extrahieren, und behalten Sie lastIndex im Blick — sobald Sie verstehen, wie er vorrückt und zurückgesetzt wird, wird das Sticky-Matching zu einem präzisen, vorhersehbaren Werkzeug.
Verwandte Themen
- Muster und Flags
- Anker: String-Anfang
^und Ende$ - Erfassungsgruppen
- Reguläre Ausdrücke in JavaScript