Start · Sprachen · JavaScript · Referenz · Nicht speichernde Gruppe: (?:...)

Nicht speichernde Gruppe: (?:...)

Keyword

Fasst ein Teilmuster eines regulären Ausdrucks zu einer Einheit zusammen, ohne den Treffer als nummerierte Gruppe zu speichern.

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

Signatur

(?:pattern)

Beschreibung

Eine nicht speichernde Gruppe (?:...) gruppiert ein Teilmuster genau wie runde Klammern (...). Der Unterschied: Der Treffer wird nicht gespeichert. Es entsteht also keine Gruppe mit Nummer, die in match()-Ergebnissen, in $1, $2 … bei replace() oder in Rückverweisen wie \1 auftaucht.

Man braucht sie immer dann, wenn Klammern nur für die Struktur des Musters gebraucht werden, zum Beispiel:

  • um einen Quantifizierer auf mehrere Zeichen anzuwenden, etwa (?:ab)+ statt ab+,
  • um eine Alternative (|) auf einen Teil des Musters zu beschränken, etwa /^(?:http|https):\/\//,
  • um die Nummerierung der „richtigen“ Gruppen stabil und übersichtlich zu halten.

Nicht speichernde Gruppen sind etwas schneller als speichernde, weil die Engine keine Teiltreffer ablegen muss, und sie machen die Ergebnis-Arrays aufgeräumter. Wenn Sie einen Teiltreffer später doch brauchen, verwenden Sie eine speichernde Gruppe (...) oder besser eine benannte Gruppe (?<name>...).

Parameter

Name Typ Default Beschreibung
$pattern Pflicht RegExp-Teilmuster Beliebiges Teilmuster, auch mit Alternativen (|), Quantifizierern oder weiteren verschachtelten Gruppen. Darf auch leer sein ((?:) passt auf die leere Zeichenkette).

Rückgabewert

Typ
—
Beschreibung
Kein eigener Wert. Die Gruppe trägt zum Gesamttreffer bei, erzeugt aber keinen Eintrag im Ergebnis-Array von exec()/match() und keine Nummer für $n oder \n.

Beispiele

Quantifizierer auf eine ganze Gruppe anwenden

const re = /^(?:ha)+!$/;

console.log(re.test('hahaha!')); // Gruppe "ha" wiederholt
console.log(re.test('haaa!'));   // nur 'a' wiederholt – kein Treffer
console.log('hahaha!'.match(re));
true false [ 'hahaha!', index: 0, input: 'hahaha!', groups: undefined ]

Vergleich: speichernd vs. nicht speichernd

const text = 'Datei: bericht.pdf';

const mitGruppe = text.match(/(\w+)\.(pdf|docx)/);
const ohneGruppe = text.match(/(\w+)\.(?:pdf|docx)/);

console.log(mitGruppe.slice(1));  // Name und Endung gespeichert
console.log(ohneGruppe.slice(1)); // nur der Dateiname
[ 'bericht', 'pdf' ] [ 'bericht' ]

Alternative begrenzen und Gruppennummern stabil halten

// Protokoll ist optional und wird nicht gespeichert – $1 bleibt die Domain
const urls = ['https://example.com/a', 'http://test.de', 'ftp://alt.org'];
const re = /^(?:https?:\/\/)?([^/]+)/;

const domains = urls
  .filter((u) => /^(?:https?):/.test(u))
  .map((u) => u.replace(re, '$1'));

console.log(domains);
[ 'example.com/a', 'test.de' ]

Wiederholtes Muster mit matchAll auswerten

// Zeitangaben wie 12:30 oder 12:30:15 – Sekunden optional, aber als Einheit
const log = 'Start 08:15, Pause 12:30:45, Ende 17:00';
const re = /\b(\d{2}):(\d{2})(?::\d{2})?\b/g;

const zeiten = [...log.matchAll(re)].map(([, h, m]) => `${h}h${m}`);
console.log(zeiten);
[ '08h15', '12h30', '17h00' ]

// Wichtig · Fallstricke

  • Keine Rückverweise möglich: Auf den Inhalt von (?:...) lässt sich weder mit \1 im Muster noch mit $1 in replace() zugreifen – die Nummerierung überspringt die Gruppe einfach.
  • Nicht verwechseln: (?=...) und (?!...) sind Lookaheads, (?<=...)/(?<!...) Lookbehinds, (?<name>...) ist eine benannte Gruppe. Nur (?: mit Doppelpunkt ist die nicht speichernde Gruppe.
  • Operator-Vorrang: | hat den niedrigsten Vorrang. /^a|b$/ bedeutet „beginnt mit a oder endet mit b“ – für „genau a oder b“ braucht es /^(?:a|b)$/.
  • Modifikatoren: Neuere Engines (ES2025, z. B. Chrome 125+, Firefox 132+) unterstützen Flag-Modifikatoren in der Form (?i:...) bzw. (?-i:...). Diese sind ebenfalls nicht speichernd, aber in älteren Umgebungen ein Syntaxfehler.
  • Die normale Syntax (?:...) funktioniert in allen Browsern und Node.js-Versionen.