Signatur
Beschreibung
RegExp.prototype[Symbol.replace]() ist die interne Implementierung hinter str.replace(regex, ersatz) und str.replaceAll(regex, ersatz). Übergibt man ein Objekt mit einer [Symbol.replace]-Methode als Muster, ruft String.prototype.replace() diese Methode auf. Der Aufruf 'abc'.replace(/b/, 'x') ist also gleichbedeutend mit /b/[Symbol.replace]('abc', 'x').
Das Verhalten hängt vom g-Flag ab: Ohne g wird nur der erste Treffer ab lastIndex (bei y) bzw. ab Position 0 ersetzt. Mit g wird lastIndex auf 0 gesetzt und alle Treffer werden ersetzt. Intern wird dafür wiederholt this.exec() aufgerufen, weshalb Unterklassen das Verhalten durch Überschreiben von exec() oder direkt von [Symbol.replace] anpassen können.
Als Ersatz ist entweder ein String mit speziellen Mustern ($&, $1…$99, $<name>, $`, $', $$) oder eine Funktion erlaubt, die für jeden Treffer aufgerufen wird und den Ersatztext zurückgibt.
Direkt aufgerufen wird die Methode selten. Sinnvoll ist sie vor allem beim Ableiten eigener RegExp-Klassen oder beim Bau eigener Muster-Objekte, die mit replace() zusammenarbeiten sollen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $str Pflicht | string | Der String, in dem ersetzt werden soll. Andere Werte werden in einen String umgewandelt. | |
| $replacement Pflicht | string | Function | Ersatztext mit optionalen $-Mustern oder eine Funktion (match, p1, …, offset, string, groups) => string, die pro Treffer aufgerufen wird. Ist es keine Funktion, wird der Wert in einen String umgewandelt. |
Rückgabewert
g) oder alle Treffer (mit g) ersetzt wurden. Der Ausgangsstring bleibt unverändert.Beispiele
Direkter Aufruf vs. String.prototype.replace()
const re = /-/g;
const datum = '2024-05-17';
console.log(re[Symbol.replace](datum, '.'));
console.log(datum.replace(re, '.'));
Benannte Gruppen und Ersatzfunktion
const re = /(?<jahr>\d{4})-(?<monat>\d{2})-(?<tag>\d{2})/g;
const text = 'Start: 2024-05-17, Ende: 2024-06-01';
// Ersatz über $<name>-Muster
console.log(re[Symbol.replace](text, '$<tag>.$<monat>.$<jahr>'));
// Ersatz über Funktion
const ergebnis = re[Symbol.replace](text, (...args) => {
const { jahr, monat, tag } = args.at(-1);
return `${Number(tag)}.${Number(monat)}.${jahr}`;
});
console.log(ergebnis);
Eigene RegExp-Unterklasse mit angepasstem Ersetzen
class ProtokollRegExp extends RegExp {
[Symbol.replace](str, replacement) {
let anzahl = 0;
const ergebnis = super[Symbol.replace](str, (...args) => {
anzahl++;
return typeof replacement === 'function' ? replacement(...args) : replacement;
});
console.log(`${anzahl} Ersetzung(en)`);
return ergebnis;
}
}
const re = new ProtokollRegExp('passwort=\\S+', 'g');
const log = 'user=anna passwort=geheim; user=ben passwort=1234';
console.log(log.replace(re, 'passwort=***'));
// Wichtig · Fallstricke
- Nur ein Treffer ohne
g: Ohne globales Flag wird nur der erste Treffer ersetzt.String.prototype.replaceAll()wirft bei einem RegExp ohnegeinenTypeError, bevor[Symbol.replace]überhaupt aufgerufen wird. lastIndexwird verändert: BeigwirdlastIndexzuerst auf 0 und am Ende wieder auf 0 gesetzt. Beiyohnegbeginnt die Suche anlastIndex, und der Wert wird danach aktualisiert. Das kann bei wiederverwendeten Regex-Objekten zu überraschenden Ergebnissen führen.$im Ersatzstring: Wenn der Ersatztext aus Benutzereingaben stammt, können$&,$1usw. ungewollt ausgewertet werden. Maskiere$als$$oder nutze eine Ersatzfunktion, die den Text unverändert zurückgibt.- Leere Treffer: Muster wie
/x*/gkönnen leer treffen. Die Engine rückt dann um ein Zeichen weiter, mit dem Flagu/vum einen ganzen Codepunkt. - Kompatibilität: Wird seit ES2015 von allen aktuellen Browsern und Node.js unterstützt. Der Internet Explorer unterstützt die Methode nicht.