Start · Sprachen · JavaScript · Referenz · Puffergrenzen-Aussage: \\A, \\z, \\Z

Puffergrenzen-Aussage: \\A, \\z, \\Z

Keyword

Prüft, ob die Position genau am Anfang (<code>\A</code>) oder Ende (<code>\z</code>, <code>\Z</code> auch vor abschließendem Zeilenumbruch) des gesamten Strings liegt – unabhängig vom <code>m</code>-Flag.

seit JavaScript TC39-Vorschlag „RegExp Buffer Boundaries“ (Stage 2 Kategorie: syntax

Signatur

/\A…/ · /…\z/ · /…\Z/

Beschreibung

Puffergrenzen-Aussagen sind Zusicherungen mit Nullbreite in regulären Ausdrücken. Sie verbrauchen kein Zeichen, sondern prüfen nur, ob die aktuelle Position an einer bestimmten Stelle des gesamten Eingabestrings liegt:

  • \A – passt nur ganz am Anfang des Strings.
  • \z – passt nur ganz am Ende des Strings.
  • \Z – passt am Ende des Strings oder direkt vor einem einzelnen abschließenden Zeilenumbruch.

Der Unterschied zu ^ und $: Diese beiden Anker ändern ihre Bedeutung, wenn das m-Flag (multiline) gesetzt ist, und passen dann auch an jedem Zeilenanfang bzw. -ende. \A, \z und \Z ignorieren das m-Flag. So lassen sich in einem einzigen Muster zeilenweise Anker (^/$ mit m) und Anker für den ganzen String kombinieren. Das kennt man aus Perl, PCRE, Python, Ruby, Java und .NET.

Wichtig: Die Syntax stammt aus dem TC39-Vorschlag RegExp Buffer Boundaries und ist noch nicht Teil von ECMAScript. Keine aktuelle Engine unterstützt sie. Für Produktivcode nimmt man heute gleichwertige Lookarounds: (?<![\s\S]) für den Anfang und (?![\s\S]) für das Ende. Die Beispiele unten zeigen beide Schreibweisen.

Parameter

Name Typ Default Beschreibung
$\A Zusicherung Anfang des gesamten Strings. Heute gleichwertig: (?<![\s\S]) oder ^ ohne m-Flag.
$\z Zusicherung Ende des gesamten Strings. Heute gleichwertig: (?![\s\S]) oder $ ohne m-Flag.
$\Z Zusicherung Ende des Strings oder die Position vor einem einzelnen abschließenden Zeilenumbruch. Heute gleichwertig etwa: (?=\n?(?![\s\S])).

Beispiele

Anfang des Strings trotz m-Flag – heute lauffähig mit Lookbehind

const text = `# Titel
# Unterpunkt
Text`;

// ^ mit m passt an JEDEM Zeilenanfang
console.log(text.match(/^# .+/gm));

// Nur die allererste Zeile – Ersatz für \A
const START = String.raw`(?<![\s\S])`;
const re = new RegExp(`${START}# .+`, 'gm');
console.log(text.match(re));

// Mit dem Vorschlag (noch NICHT lauffähig):
// text.match(/\A# .+/gm);
[ '# Titel', '# Unterpunkt' ] [ '# Titel' ]

Zeilen- und Stringanker in einem Muster kombinieren

// Prüfen, ob jede Zeile ein key=value-Paar ist UND der ganze String
// damit vollständig abgedeckt ist
const isConfig = (s) =>
  /(?<![\s\S])(?:^\w+=[^\n]*$\n?)+(?![\s\S])/m.test(s);

console.log(isConfig('host=localhost\nport=8080\n'));
console.log(isConfig('host=localhost\nkaputt\n'));

// Vorschlag-Syntax: /\A(?:^\w+=[^\n]*$\n?)+\z/m
true false

\Z nachbilden: Ende oder vor abschließendem Zeilenumbruch

// Ersatz für \Z
const endsWithSemicolon = /;(?=\n?(?![\s\S]))/;

console.log(endsWithSemicolon.test('let a = 1;'));
console.log(endsWithSemicolon.test('let a = 1;\n'));
console.log(endsWithSemicolon.test('let a = 1;\n\n'));

// Vorschlag-Syntax: /;\Z/
true true false

Aktuelles Verhalten der Escapes erkennen

// Ohne u-Flag ist \A heute nur ein unnötig maskiertes "A"
console.log(/\A/.test('A'));

// Mit u- oder v-Flag ist es ein Syntaxfehler
try {
  new RegExp(String.raw`\A`, 'u');
} catch (e) {
  console.log(e.name);
}
true SyntaxError

// Wichtig · Fallstricke

Noch nicht standardisiert: \A, \z und \Z gehören zu einem TC39-Vorschlag (Stage 2). Keine Engine setzt sie bisher um. Weder Browser noch Node.js oder Deno unterstützen sie.

Gefährliche Altlast ohne u-Flag: In Mustern ohne u- bzw. v-Flag gelten \A, \z und \Z heute als Identitäts-Escapes. Sie passen dann einfach auf die Buchstaben A, z bzw. Z. Ein aus Perl oder Python übernommenes Muster wie /\Afoo\z/ wirft deshalb keinen Fehler, prüft aber etwas völlig anderes. Deshalb sollen die neuen Anker laut Vorschlag wohl nur mit u/v-Flag gelten. Dort ist die Syntax heute ein SyntaxError.

Ersatz für Produktivcode:

  • Ohne m-Flag reichen ^ und $. Dabei passt $ in JavaScript nicht vor einem abschließenden \n, anders als in Perl oder Python.
  • Mit m-Flag nimmt man (?<![\s\S]) für den Anfang und (?![\s\S]) für das Ende. Lookbehind wird seit ES2018 unterstützt, in Safari erst ab Version 16.4.

\Z und Zeilenumbrüche: Welche Zeichen als abschließender Zeilenumbruch gelten (nur \n oder auch \r\n, \u2028 usw.), ist im Vorschlag noch nicht endgültig festgelegt. Wer \Z heute nachbildet, sollte das gewünschte Verhalten ausdrücklich im Muster festlegen, z. B. mit (?=(?:\r?\n)?(?![\s\S])).

Sticky-Flag und lastIndex: Die Anker beziehen sich immer auf den gesamten String, nicht auf die Startposition aus lastIndex. Für „ab hier passen“ ist das y-Flag das richtige Werkzeug.