Start · Sprachen · JavaScript · Referenz · RegExp.prototype.sticky

RegExp.prototype.sticky

Eigenschaft

Gibt <code>true</code> zurück, wenn der reguläre Ausdruck mit dem <code>y</code>-Flag (sticky) erstellt wurde, sonst <code>false</code>.

seit JavaScript ES2015 Kategorie: method-property

Signatur

get RegExp.prototype.sticky

Beschreibung

sticky ist eine schreibgeschützte Zugriffseigenschaft (Getter) auf RegExp.prototype. Sie gibt an, ob ein regulärer Ausdruck mit dem Flag y erstellt wurde, entweder als Literal /muster/y oder über new RegExp("muster", "y").

Mit dem y-Flag sucht der Ausdruck nur genau an der Position lastIndex. Die Suche wandert also nicht weiter durch die Zeichenkette, sondern der Treffer muss direkt an dieser Stelle beginnen. Gibt es dort keinen Treffer, liefern exec() und test() einen Fehlschlag, und lastIndex wird auf 0 zurückgesetzt. Bei einem Treffer rückt lastIndex ans Ende des Treffers vor.

Das ist vor allem für Tokenizer, Lexer und Parser nützlich. Dort soll eine Eingabe Stück für Stück ohne Lücken zerlegt werden, und man will nicht versehentlich Zeichen überspringen. Die Eigenschaft sticky selbst braucht man meist nur, um in allgemeinem Code zu prüfen, wie ein übergebener Ausdruck konfiguriert ist, zum Beispiel bevor man lastIndex setzt.

Rückgabewert

Typ
boolean
Beschreibung
true, wenn das y-Flag gesetzt ist, sonst false. Beim Zugriff direkt auf RegExp.prototype ist der Wert undefined.

Beispiele

Flag abfragen

const literal = /foo/y;
const konstruktor = new RegExp('foo', 'gy');
const normal = /foo/g;

console.log(literal.sticky);
console.log(konstruktor.sticky);
console.log(normal.sticky);
console.log(konstruktor.flags);
true true false gy

Suche nur an der Position lastIndex

const str = 'foo bar foo';
const re = /foo/y;

console.log(re.test(str), re.lastIndex); // Treffer an Position 0
console.log(re.test(str), re.lastIndex); // an Position 3 steht ' ', kein Treffer

re.lastIndex = 8;
console.log(re.test(str), re.lastIndex); // Treffer genau an Position 8
true 3 false 0 true 11

Einfacher Tokenizer ohne übersprungene Zeichen

const tokenize = (input) => {
  const re = /\s*(\d+|[-+*/()])/y;
  const tokens = [];
  while (re.lastIndex < input.length) {
    const pos = re.lastIndex;
    const m = re.exec(input);
    if (!m) throw new SyntaxError(`Unerwartetes Zeichen an Position ${pos}`);
    tokens.push(m[1]);
  }
  return tokens;
};

console.log(tokenize('12 + (3*4)'));
try {
  tokenize('1 + a');
} catch (e) {
  console.log(e.message);
}
[ '12', '+', '(', '3', '*', '4', ')' ] Unerwartetes Zeichen an Position 3

Übergebenen Ausdruck prüfen

const matchAt = (regex, text, index) => {
  if (!regex.sticky) {
    // Kopie mit y-Flag erzeugen, das Original bleibt unverändert
    regex = new RegExp(regex.source, regex.flags + 'y');
  }
  regex.lastIndex = index;
  return regex.exec(text)?.[0] ?? null;
};

console.log(matchAt(/\d+/, 'abc 123', 4));
console.log(matchAt(/\d+/, 'abc 123', 0));
123 null

// Wichtig · Fallstricke

  • Nur lesbar: sticky hat keinen Setter. Eine Zuweisung wie re.sticky = true wird ohne Fehlermeldung ignoriert; im Strict Mode wirft sie einen TypeError. Um das Flag zu ändern, erzeugt man einen neuen Ausdruck mit new RegExp(re.source, re.flags + 'y').
  • ^ mit y: ^ passt auch mit Sticky-Flag nur am Anfang der Eingabe (bzw. mit m am Zeilenanfang), nicht an lastIndex. /^foo/y mit lastIndex = 4 findet in 'bar foo' also nichts.
  • Zustand über lastIndex: Sticky-Ausdrücke speichern ihren Zustand wie globale Ausdrücke. Nutzt man dieselbe Instanz mehrfach, kann ein alter lastIndex-Wert zu unerwarteten Fehlschlägen führen. Wenn nötig, lastIndex vorher auf 0 setzen.
  • String-Methoden: String.prototype.split() ignoriert das y-Flag. replace() und match() ohne g ersetzen bzw. finden nur an der Position lastIndex. matchAll() und replaceAll() brauchen zusätzlich das g-Flag.
  • Kompatibilität: Wird von allen modernen Browsern und von Node.js 6+ unterstützt. Der Internet Explorer kennt das Flag nicht; dort wirft schon das Literal /x/y einen Syntaxfehler.