Frage Wie ersetzt man alle Vorkommen einer Zeichenkette in JavaScript?


Ich habe diese Zeichenfolge:

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

Tun

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

scheint nur das erste Auftreten von zu entfernen abc in der Zeichenfolge oben. Wie kann ich ersetzen? alle Vorkommen davon?


3164
2017-07-17 17:53


Ursprung


Antworten:


Der Vollständigkeit halber habe ich darüber nachgedacht, mit welcher Methode ich das machen soll. Es gibt grundsätzlich zwei Möglichkeiten, dies zu tun, wie es die anderen Antworten auf dieser Seite vorschlagen.

Hinweis: Im Allgemeinen wird die Erweiterung der integrierten Prototypen in JavaScript nicht empfohlen. Ich biete als Erweiterung des String - Prototyps nur zu Illustrationszwecken verschiedene Implementierungen einer hypothetischen Standardmethode an String Eingebauter Prototyp.


Regular Expression Based Implementation

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

Split und 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 im Hinblick auf Effizienz hinter den Kulissen arbeiten, neigte ich dazu, mich in die Vergangenheit zu lehnen und der Implementierung beizutreten, ohne an Leistung zu denken. Als ich mich gefragt habe, was effizienter ist und mit welchem ​​Abstand, habe ich es als Ausrede benutzt, um es herauszufinden.

Auf meinem Chrome Windows 8-Computer Die auf regulären Ausdrücken basierende Implementierung ist die schnellste, mit dem Split- und Join-Implementierung ist 53% langsamer. Das heißt, die regulären Ausdrücke sind für den von mir verwendeten Lorem-Ipsum-Eingang doppelt so schnell.

Schau dir das an Benchmark Ausführen dieser beiden Implementierungen gegeneinander.


Wie im folgenden Kommentar von @ThomasLeduc und anderen erwähnt, könnte es ein Problem mit der regulären Ausdruck-basierten Implementierung geben search enthält bestimmte Zeichen, die als reserviert sind Sonderzeichen in regulären Ausdrücken. Die Implementierung setzt voraus, dass der Aufrufer die Zeichenfolge im Voraus entschlüsselt oder nur Zeichenfolgen übergibt, die keine Zeichen in der Tabelle enthalten Reguläre Ausdrücke (MDN).

MDN bietet auch eine Implementierung, um unseren Strings zu entkommen. Es wäre schön, wenn dies auch standardisiert wäre RegExp.escape(str)aber leider existiert es nicht:

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

Wir könnten anrufen escapeRegExp in unserem String.prototype.replaceAll Bei der Implementierung bin ich mir jedoch nicht sicher, inwieweit sich dies auf die Performance auswirkt (möglicherweise sogar für Strings, für die der Escape nicht benötigt wird, wie alle alphanumerischen Strings).


1627
2017-07-12 01:46



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

Als Antwort auf den Kommentar:

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

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

Als Antwort auf Klicken Sie auf UpvoteKommentar, Sie könnten es noch mehr vereinfachen:

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

Hinweis: Reguläre Ausdrücke enthalten spezielle (Meta -) Zeichen, und als solche ist es gefährlich, blind ein Argument in der find Funktion oben ohne Vorverarbeitung, um diese Zeichen zu entkommen. Dies ist in der abgedeckt Mozilla-Entwickler-Netzwerkist es JavaScript Guide für reguläre Ausdrücke, wo sie die folgende Dienstprogrammfunktion präsentieren:

function escapeRegExp(str) {
    return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}

Also um das zu machen replaceAll() Funktion über sicherer, könnte es zu dem folgenden geändert werden, wenn Sie auch einschließen escapeRegExp:

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

3586
2017-07-17 17:54



Hinweis: Verwenden Sie das nicht in echtem Code.

Als Alternative zu regulären Ausdrücken für eine einfache literale Zeichenfolge könnten Sie verwenden

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

Das allgemeine Muster ist

str.split(search).join(replacement)

Dies war früher manchmal schneller als die Verwendung replaceAll und ein regulärer Ausdruck, aber das scheint in modernen Browsern nicht mehr der Fall zu sein. Also sollte dies wirklich nur als ein schneller Hack verwendet werden, um zu vermeiden, dem regulären Ausdruck zu entkommen, nicht in echtem Code.


1193
2017-07-17 20:29



Verwenden eines regulären Ausdrucks mit dem g flag set wird alle ersetzen:

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


505
2018-05-06 23:18



Hier ist eine String-Prototyp-Funktion basierend auf der angenommenen Antwort:

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

BEARBEITEN 

Wenn dein find enthält Sonderzeichen, dann musst du ihnen entkommen:

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

Geige: http://jsfiddle.net/cdbzL/


90
2018-02-11 23:03



Aktualisieren:

Es ist etwas spät für ein Update, aber da ich gerade auf diese Frage gestoßen bin und bemerkt habe, dass meine vorherige Antwort keine ist, bin ich glücklich mit. Da bei der Frage ein einzelnes Wort ersetzt wurde, ist es unglaublich, dass niemand daran gedacht hat, Wortgrenzen zu verwenden (\b)

'a cat is not a caterpillar'.replace(/\bcat\b/gi,'dog');
//"a dog is not a caterpillar"

Dies ist eine einfache Regex, die es in den meisten Fällen vermeidet, Teile von Wörtern zu ersetzen. Allerdings ein Strich - gilt immer noch als Wortgrenze. So können in diesem Fall Conditionals verwendet werden, um den Austausch von Strings zu vermeiden cool-cat:

'a cat is not a cool-cat'.replace(/\bcat\b/gi,'dog');//wrong
//"a dog is not a cool-dog" -- nips
'a cat is not a cool-cat'.replace(/(?:\b([^-]))cat(?:\b([^-]))/gi,'$1dog$2');
//"a dog is not a cool-cat"

Im Grunde ist diese Frage die gleiche wie die Frage hier: Javascript ersetzt "'" durch "' '"

@ Mike, überprüfen Sie die Antwort, die ich dort gab ... regexp ist nicht die einzige Möglichkeit, mehrere Vorkommen eines subsrting, weit davon zu ersetzen. Denk flexibel, denke gespalten!

var newText = "the cat looks like a cat".split('cat').join('dog');

Alternativ, um den Austausch von Wortteilen zu verhindern - was auch die genehmigte Antwort tun wird! Sie können dieses Problem umgehen, indem Sie reguläre Ausdrücke verwenden, die, zugegebenermaßen, etwas komplexer und damit auch etwas langsamer sind:

var regText = "the cat looks like a cat".replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");

Die Ausgabe entspricht der angenommenen Antwort, wobei jedoch der Ausdruck / cat / g für diese Zeichenfolge verwendet wird:

var oops = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/cat/g,'dog');
//returns "the dog looks like a dog, not a dogerpillar or cooldog" ?? 

Hoppla, das ist wahrscheinlich nicht das, was Sie wollen. Was ist dann? IMHO, eine Regex, die nur "Katze" bedingt ersetzt. (also nicht Teil eines Wortes), so:

var caterpillar = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
//return "the dog looks like a dog, not a caterpillar or coolcat"

Ich schätze, das entspricht Ihren Bedürfnissen. Es ist natürlich nicht vollständig sicher, aber es sollte genug sein, um Sie zu starten. Ich würde empfehlen, mehr auf diesen Seiten zu lesen. Dies wird nützlich sein, um diesen Ausdruck zu perfektionieren, um Ihre spezifischen Bedürfnisse zu erfüllen.

http://www.javascriptkit.com/jsref/regexp.shtml

http://www.regular-expressions.info


Endgültige Ergänzung:

Angesichts der Tatsache, dass diese Frage immer noch viele Ansichten bekommt, dachte ich, ich könnte ein Beispiel hinzufügen .replace verwendet mit einer Rückruffunktion. In diesem Fall vereinfacht es den Ausdruck dramatisch und bietet noch mehr Flexibilität, wie Ersetzen durch korrekte Großschreibung oder Ersetzen von beiden cat und cats auf einmal:

'Two cats are not 1 Cat! They\'re just cool-cats, you caterpillar'
   .replace(/(^|.\b)(cat)(s?\b.|$)/gi,function(all,char1,cat,char2)
    {
       //check 1st, capitalize if required
       var replacement = (cat.charAt(0) === 'C' ? 'D' : 'd') + 'og';
       if (char1 === ' ' && char2 === 's')
       {//replace plurals, too
           cat = replacement + 's';
       }
       else
       {//do not replace if dashes are matched
           cat = char1 === '-' || char2 === '-' ? cat : replacement;
       }
       return char1 + cat + char2;//return replacement string
    });
//returns:
//Two dogs are not 1 Dog! They're just cool-cats, you caterpillar

75
2018-03-01 10:02



Übereinstimmung mit einem globalen regulären Ausdruck:

anotherString = someString.replace(/cat/g, 'dog');

45
2018-05-06 23:23



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

Oder probieren Sie die replaceAll-Funktion von hier aus:

Was sind nützliche JavaScript-Methoden, die integrierte Objekte erweitern?

str = str.replaceAll('abc', ''); OR

var search = 'abc';
str = str.replaceAll(search, '');

BEARBEITEN: Klärung über replaceAll Verfügbarkeit

Die Methode 'replaceAll' wird dem String-Prototyp hinzugefügt. Dies bedeutet, dass es für alle String-Objekte / Literale verfügbar ist.

Z.B.

var output = "test this".replaceAll('this', 'that');  //output is 'test that'.
output = output.replaceAll('that', 'this'); //output is 'test this'

34
2017-07-17 17:55



Angenommen, Sie möchten alle 'abc' durch 'x' ersetzen:

let some_str = 'abc def def lom abc abc def'.split('abc').join('x')
console.log(some_str) //x def def lom x x def

Ich versuchte über etwas einfacheres nachzudenken, als den String-Prototyp zu modifizieren.


29
2017-09-10 14:59