5465 Stimmen

Ersetzen aller Vorkommen einer Zeichenkette in JavaScript

Ich habe diese Zeichenfolge in meinem JavaScript-Code:

"Test abc test test abc test test test abc test test abc"

Tun:

str = str.replace('abc', '');

Scheint nur das erste Vorkommen von abc in der obigen Zeichenfolge.

Wie kann ich die alle Vorkommnisse davon?

5215voto

Sean Bright Punkte 114347

Ab August 2020: Moderne Browser bieten Unterstützung para el String.replaceAll() Methode definiert durch die ECMAScript 2021 Sprachspezifikation.


Für ältere/Legacy-Browser:

function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}

Diese Antwort hat sich folgendermaßen entwickelt:

str = str.replace(/abc/g, '');

Als Antwort auf den Kommentar "Was ist, wenn 'abc' als Variable übergeben wird?":

var find = 'abc';
var re = new RegExp(find, 'g');

str = str.replace(re, '');

Als Antwort auf Upvote klicken Sie könnten es noch weiter vereinfachen:

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(find, 'g'), replace);
}

Nota: Reguläre Ausdrücke enthalten spezielle (Meta-)Zeichen, und daher ist es gefährlich, blind ein Argument in der find Funktion ohne Vorverarbeitung, um diese Zeichen zu entschlüsseln. Dies wird im Abschnitt Mozilla-Entwickler-Netzwerk 's JavaScript-Anleitung für reguläre Ausdrücke wo die folgende Funktion vorgestellt wird (die sich seit dem Verfassen dieser Antwort mindestens zweimal geändert hat; überprüfen Sie also die MDN-Site auf mögliche Aktualisierungen):

function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

Um also die replaceAll() Funktion oben sicherer ist, könnte sie in die folgende geändert werden, wenn Sie auch die escapeRegExp :

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}

2536voto

Cory Gross Punkte 36115

Der Vollständigkeit halber habe ich mir überlegt, welche Methode ich dafür verwenden sollte. Wie in den anderen Antworten auf dieser Seite vorgeschlagen, gibt es grundsätzlich zwei Möglichkeiten, dies zu tun.

Nota: Im Allgemeinen wird die Erweiterung der eingebauten Prototypen in JavaScript nicht empfohlen. Ich biete Erweiterungen des String-Prototyps nur zur Veranschaulichung an und zeige verschiedene Implementierungen einer hypothetischen Standardmethode auf der String eingebauter Prototyp.


Implementierung mit regulären Ausdrücken

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.replace(new RegExp(search, 'g'), replacement);
};

Split and Join (funktionale) Implementierung

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.split(search).join(replacement);
};

Da ich nicht allzu viel darüber weiß, wie reguläre Ausdrücke hinter den Kulissen in Bezug auf die Effizienz funktionieren, neigte ich in der Vergangenheit dazu, der Split- und Join-Implementierung den Vorzug zu geben, ohne über die Leistung nachzudenken. Als ich mich fragte, was effizienter ist und in welchem Umfang, habe ich das als Vorwand genommen, um es herauszufinden.

Auf meinem Chrome Windows 8 Rechner, die auf regulären Ausdrücken basierende Implementierung ist die schnellste , mit dem die Implementierung von Split und Join ist 53 % langsamer . Das bedeutet, dass die regulären Ausdrücke doppelt so schnell für die von mir verwendete Lorem-ipsum-Eingabe sind.

Sehen Sie sich das an Benchmark diese beiden Implementierungen gegeneinander antreten zu lassen.


Wie in dem unten stehenden Kommentar von @ThomasLeduc und anderen erwähnt, könnte es ein Problem mit der auf regulären Ausdrücken basierenden Implementierung geben, wenn search enthält bestimmte Zeichen, die reserviert sind als Sonderzeichen in regulären Ausdrücken . Die Implementierung geht davon aus, dass der Aufrufer die Zeichenkette vorher entschlüsselt oder nur Zeichenketten übergibt, die nicht die Zeichen in der Tabelle in _Reguläre Ausdrücke_ (MDN).

MDN bietet auch eine Implementierung, um unsere Zeichenketten zu entschlüsseln. Es wäre schön, wenn dies auch standardisiert wäre als RegExp.escape(str) aber leider gibt es sie nicht:

function escapeRegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}

Wir könnten anrufen escapeRegExp innerhalb unserer String.prototype.replaceAll Implementierung bin ich mir jedoch nicht sicher, wie sehr dies die Leistung beeinträchtigen wird (möglicherweise sogar für Zeichenketten, für die die Escape-Funktion nicht benötigt wird, wie z. B. alle alphanumerischen Zeichenketten).

2392voto

Matthew Crumley Punkte 98564

Aktualisierung: In den neuesten Versionen der meisten gängigen Browser können Sie replaceAll wie hier gezeigt:

let result = "1 abc 2 abc 3".replaceAll("abc", "xyz");
// `result` is "1 xyz 2 xyz 3"

Aber prüfen Kann ich die oder eine andere Kompatibilitätstabelle, um sicherzugehen, dass die Browser, auf die Sie abzielen, diese Funktion bereits unterstützen.


Für Node und Kompatibilität mit älteren/nicht aktuellen Browsern:

Hinweis: Verwenden Sie die folgende Lösung nicht in leistungskritischem Code.

Als Alternative zu regulären Ausdrücken für eine einfache Zeichenkette können Sie auch

str = "Test abc test test abc test...".split("abc").join("");

Das allgemeine Muster ist

str.split(search).join(replacement)

Dies war in einigen Fällen schneller als die Verwendung von replaceAll und einem regulären Ausdruck, aber das scheint in modernen Browsern nicht mehr der Fall zu sein.

Benchmark: https://jsben.ch/TZYzj

Schlussfolgerung:

Wenn Sie einen leistungsrelevanten Anwendungsfall haben (z. B. die Verarbeitung von Hunderten von Zeichenketten), sollten Sie die Regexp-Methode verwenden. Aber für die meisten typischen Anwendungsfälle lohnt es sich, sich nicht um Sonderzeichen kümmern zu müssen.

810voto

Adam A Punkte 14140

Die Verwendung eines regulären Ausdrucks mit der g gesetzt, werden alle ersetzt:

someString = 'the cat looks like a cat';
anotherString = someString.replace(/cat/g, 'dog');
// anotherString now contains "the dog looks like a dog"

Siehe auch hier

139voto

jesal Punkte 7504

Hier ist eine String-Prototyp-Funktion auf der Grundlage der akzeptierten Antwort:

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find, 'g'), replace);
};

EDITAR

Wenn Ihr find Sonderzeichen enthalten, müssen Sie diese ausblenden:

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};

Fiedel: http://jsfiddle.net/cdbzL/

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X