Signatur
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)+stattab+, - 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
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));
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
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);
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);
// Wichtig · Fallstricke
- Keine Rückverweise möglich: Auf den Inhalt von
(?:...)lässt sich weder mit\1im Muster noch mit$1inreplace()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.