Wie ersetze ich alle Vorkommen eines Strings?

4380

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 Vorkommen von abcin der obigen Zeichenfolge zu entfernen .

Wie kann ich alle Vorkommen ersetzen ?

Klicken Sie auf Upvote
quelle
5
Welches Ergebnis erwarten Sie, wenn Sie alle Vorkommen von abain ababadurch ersetzen ca? caba? abca? cca?
Reinierpost
String.prototype.replaceAll()Wird in Safari 13.1 ausgeliefert und ist jetzt in Firefox Nightly und Chrome Dev und Canary erhältlich und wird in Firefox 77 und Chrome 85 ausgeliefert. Es ist noch nicht in MDN dokumentiert, aber github.com/tc39/proposal-string-replaceall#high-level-api einen Erklärer hat: „wenn search ein String ist, String.prototype.replaceAllersetzt alle Vorkommen des search (als ob .split(searchValue).join(replaceValue)oder ein globaler und ordnungsgemäß entkam regulärer Ausdruck verwendet worden ist). Wenn searchValue ein nicht globaler regulärer Ausdruck ist, wird String.prototype.replaceAlleine Ausnahme ausgelöst.
Sideshowbarker

Antworten:

1610

Hinweis: Verwenden Sie dies nicht in leistungskritischem Code.

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

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 replaceAllund ein regulärer Ausdruck, aber dies scheint in modernen Browsern nicht mehr der Fall zu sein.

Benchmark: https://jsperf.com/replace-all-vs-split-join

Schlussfolgerung: Wenn Sie einen leistungskritischen Anwendungsfall haben (z. B. die Verarbeitung von Hunderten von Zeichenfolgen), verwenden Sie die Regexp-Methode. Für die meisten typischen Anwendungsfälle lohnt es sich jedoch, sich keine Gedanken über Sonderzeichen machen zu müssen.

Matthew Crumley
quelle
147
Es überraschte mich, da ich erwarten würde, dass diese Methode mehr Objekte zuweist, mehr Müll erzeugt und somit länger dauert, aber als ich sie tatsächlich in einem Browser testete, war diese Methode durchweg etwa 20% schneller als die akzeptierte Antwort. Die Ergebnisse können natürlich variieren.
MgSam
42
Ich war selbst neugierig und habe Folgendes eingerichtet: jsperf.com/replace-all-vs-split-join . Es scheint, dass v8 im Vergleich zu anderen Javascript-Engines beim Teilen / Verbinden von Arrays einfach verrückt schnell ist.
Fabi
8
Sehr schön - erspart Ihnen auch die Möglichkeit schlechter RegExps bei der Übergabe von Sonderzeichen. Ich füge ein generisches Flag für "finde dies und ersetze es" in einer Objekteigenschaft hinzu, war aber besorgt, ob ich "ersetzen" musste. oder "}" und vergessen, dass ich 3 Monate später RegEx verwendet habe!
tobriand
9
Und als String.prototype : String.prototype.replaceAll = function(f,r){return this.split(f).join(r);}. Verwendung: "My string".replaceAll('st', '');produziert "Mein Ring"
MacroMan
8
Ich sehe keinen Grund für die Warnung, dies nicht in der Produktion zu verwenden. Es ist nicht mehr ein Hack als das Entkommen einer Regex, nur weil Sie mehrere Vorkommen ersetzen möchten, aber überhaupt keine Regex benötigen. Wickeln Sie diesen sogenannten "Hack" replaceAlleinfach in eine nette Funktion ein, und er wird genauso lesbar wie alles andere. Da die Leistung nicht schlecht ist, gibt es keinen Grund, diese Lösung zu vermeiden.
Youen
4383
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 den Kommentar von Click Upvote können Sie ihn noch weiter vereinfachen:

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

Hinweis: Reguläre Ausdrücke enthalten Sonderzeichen (Metazeichen). Daher ist es gefährlich, ein Argument in der findobigen Funktion blind zu übergeben, ohne es vorzuverarbeiten, um diesen Zeichen zu entkommen. Diese in dem abgedeckt ist Mozilla Developer Network ‚s JavaScript - Leitfaden für Reguläre Ausdrücke , in denen sie die folgende Nutzenfunktion darstellen (die zumindest verändert hat zweimal da diese Antwort wurde ursprünglich geschrieben, so stellen Sie sicher , dass die MDN Website für potenzielles Updates suchen):

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

Um die replaceAll()oben genannte Funktion sicherer zu machen , kann sie wie folgt geändert werden, wenn Sie auch Folgendes angeben escapeRegExp:

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
Sean Bright
quelle
4
Reguläre Ausdrücke sind die einzige Möglichkeit, dies "out of the box" zu erreichen, ohne Ihre eigene 'replaceAll'-Methode zu implementieren. Ich schlage ihre Verwendung nicht nur vor, um sie zu verwenden.
Sean Bright
10
Dies ist meine eigene Funktion aus diesem Kommentar: function replaceAll(find, replace,str) { var re = new RegExp(find, 'g'); str = str.replace(re, replace); return str; }
Klicken Sie auf Upvote
47
Die größte Einschränkung der replaceAllImplementierung ist, dass sie nicht funktioniert, wenn sie findMetazeichen enthält.
Martin Ender
1
@ SeanBright du hast recht. Ich habe Ihr Javascript in einem PHP-Code verwendet, daher musste ich einen zusätzlichen Backslash hinzufügen, um zu entkommen. Auf der Geige ist Ihr Code perfekt. Ich hätte nachsehen sollen. Entschuldigung jsfiddle.net/7y19xyq8
Onimusha
2437

Der Vollständigkeit halber habe ich mir überlegt, mit welcher Methode ich das machen soll. Grundsätzlich gibt es zwei Möglichkeiten, dies zu tun, wie in den anderen Antworten auf dieser Seite vorgeschlagen.

Hinweis: Im Allgemeinen wird das Erweitern der in JavaScript integrierten Prototypen nicht empfohlen. Ich stelle den String-Prototyp lediglich zur Veranschaulichung als Erweiterung zur Verfügung und zeige verschiedene Implementierungen einer hypothetischen Standardmethode für den Stringeingebauten Prototyp.


Implementierung auf Basis regulärer Ausdrücke

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 zu viel darüber wusste, wie reguläre Ausdrücke hinter den Kulissen in Bezug auf Effizienz funktionieren, neigte ich dazu, mich in der Vergangenheit der Aufteilung zuzuwenden und mich der Implementierung anzuschließen, ohne über die Leistung nachzudenken. Als ich mich fragte, was effizienter war und mit welchem ​​Abstand, benutzte ich es als Ausrede, um es herauszufinden.

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

Schauen Sie sich diesen Benchmark an , in dem diese beiden Implementierungen gegeneinander ausgeführt werden.


Wie im folgenden Kommentar von @ThomasLeduc und anderen erwähnt, kann es zu Problemen bei der Implementierung auf der Basis regulärer Ausdrücke kommen, wenn searchbestimmte Zeichen enthalten sind, die in regulären Ausdrücken als Sonderzeichen reserviert sind . Bei der Implementierung wird davon ausgegangen, dass der Aufrufer die Zeichenfolge zuvor verlässt oder nur Zeichenfolgen übergibt, die in Regular Expressions (MDN) keine Zeichen in der Tabelle enthalten .

MDN bietet auch eine Implementierung, um unseren Zeichenfolgen 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 escapeRegExpinnerhalb unserer String.prototype.replaceAllImplementierung aufrufen , ich bin mir jedoch nicht sicher, wie stark sich dies auf die Leistung auswirkt (möglicherweise sogar für Zeichenfolgen, für die das Escape nicht benötigt wird, wie bei allen alphanumerischen Zeichenfolgen).

Cory Gross
quelle
8
Unter Android 4.1 ist die Regexp-Methode 15% schneller, aber Sie entgehen nicht dem Ausdruck, nach dem gesucht werden soll, sodass dieser Benchmark unvollständig ist.
andreszs
33
Es gibt ein Problem mit dieser Lösung. Wenn Ihre Suchzeichenfolge Sonderzeichen eines regulären Ausdrucks enthält, werden sie interpretiert. Ich empfehle die Antwort von @Sandy Unitedwolf.
Thomas Leduc
2
Der erste wird dies tun: 'bla.bla'.replaceAll ('. ',' _ '); "_______". Der zweite wird 'bla_bla' machen, was allgemeiner ist, was Sie tun möchten.
RobKohr
1
@ThomasLeduc es sieht so aus, als ob das von Ihnen erwähnte Problem mit lodash => lodash.com/docs/4.17.5#escapeRegExp
Matthew Beck am
1
Lassen Sie dies hier für zukünftige Zuschauer, die sich auch fragen, warum das Erweitern des nativen Objekts eine schlechte Idee ist: stackoverflow.com/questions/14034180/…
Ben Cooper
692

Die Verwendung eines regulären Ausdrucks mit ggesetztem Flag ersetzt alle:

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

Adam A.
quelle
15
Ein bisschen albern finde ich, aber die globale Regex von JS ist die einzige Möglichkeit, mehrere Ersetzungen vorzunehmen.
Mike
5
Nun, technisch gesehen können Sie var sourceTextdie Anzahl der Instanzen ( numOfInstances) mit substringoder teilen und die Länge (unter anderem) von thatWhichYouWantToReplacedo for (var i = 0; i < numOfInstances; i++){ sourceText = sourceText.replace('thatWhichYouWantToReplace', '');} zählen oder noch einfacher eine while-Schleife ( while sourceText.indexOf(thatWhichYouWantToReplace > -1){ sourceText = sourceText.replace(...)) verwenden, aber ich verstehe nicht, warum Sie dies möchten Machen Sie es so, wenn die Verwendung /gso einfach und wahrscheinlich leistungsfähiger ist.
Zargold
@Zargold Sie möchten eine Schleife erstellen, um sicherzustellen, dass Sie auch nach dem Ersetzen alle Instanzen ersetzt haben, was ein ziemlich häufiges Problem ist. Siehe meine Antwort unten stackoverflow.com/a/26089052/87520
SamGoody
109

Hier ist eine String-Prototyp-Funktion, die auf der akzeptierten Antwort basiert:

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

BEARBEITEN

Wenn Ihr findTestament Sonderzeichen enthält, müssen Sie 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/

Jesus
quelle
5
Aber was ist, wenn es findZeichen wie .oder enthält $, die in Regex eine besondere Bedeutung haben?
Callum
1
@callum In diesem Fall müssten Sie Ihre Suchvariable maskieren (siehe oben bearbeiten).
Jesus
Jesus, dies ist eine wunderbare Lösung für ein Problem beim Ersetzen von Zeichenfolgen, auf das ich gestoßen bin, und es überwindet anscheinend die "Unveränderlichkeit" von Zeichenfolgen in JavaScript. Könnten Sie oder jemand anderes erklären, wie diese Prototypfunktion die Unveränderlichkeit von Zeichenfolgen außer Kraft setzt? Das funktioniert ; Ich möchte nur diese Nebenfrage verstehen, die sie aufwirft.
Tom
1
@Tom: Die Unveränderlichkeit wird überhaupt nicht überwunden : Erstellt var str = thiseinen zweiten Verweis auf die unveränderliche Zeichenfolge, auf die die replaceMethode angewendet wird, die wiederum eine neue unveränderliche Zeichenfolge zurückgibt . Diese Prototypfunktionen geben eine neue unveränderliche Zeichenfolge zurück. Wenn nicht, können Sie schreiben someStrVar.replaceAll('o', '0');und someStrVarwerden geändert. Stattdessen müssen Sie someStrVar = someStrVar.replaceAll('o', '0');<- neu zuweisen schreiben , um die Variable so einzustellen, dass sie die neue unveränderliche Zeichenfolge enthält . Daran führt kein Weg vorbei. Versuchen Sie in der Konsole:x = 'foobar'; x.replaceAll('o', '0'); x;
Elias Van Ootegem
87

Aktualisieren:

Es ist etwas spät für ein Update, aber da ich gerade über diese Frage gestolpert bin und festgestellt habe, dass meine vorherige Antwort nicht die ist, mit der ich zufrieden bin. Da die Frage das Ersetzen eines einzelnen Wortes betraf, 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 in den meisten Fällen das Ersetzen von Wortteilen vermeidet. Ein Bindestrich -wird jedoch immer noch als Wortgrenze betrachtet. In diesem Fall können also Bedingungen verwendet werden, um das Ersetzen von Zeichenfolgen wie den cool-catfolgenden zu vermeiden :

'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 dieselbe wie die Frage hier: Javascript ersetzt "'" durch "' '"

@ Mike, überprüfen Sie die Antwort, die ich dort gegeben habe ... Regexp ist nicht die einzige Möglichkeit, mehrere Vorkommen eines Abonnements zu ersetzen, weit davon entfernt. Denken Sie flexibel, denken Sie gespalten!

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

Alternativ, um zu verhindern, dass Wortteile ersetzt werden - was auch für die genehmigte Antwort der Fall ist! Sie können dieses Problem mit regulären Ausdrücken umgehen, die zugegebenermaßen etwas komplexer und als Ergebnis 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 akzeptierten Antwort, verwendet jedoch den Ausdruck / cat / g für diese Zeichenfolge:

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 du willst. Was ist dann? IMHO, eine Regex, die "Katze" nur bedingt ersetzt. (dh nicht Teil eines Wortes), wie 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 vermute, das entspricht Ihren Bedürfnissen. Es ist natürlich nicht vollständig sicher, aber es sollte ausreichen, um Ihnen den Einstieg zu erleichtern. Ich würde empfehlen, auf diesen Seiten mehr zu lesen. Dies wird sich als nützlich erweisen, um diesen Ausdruck so zu perfektionieren, dass er Ihren spezifischen Anforderungen entspricht.

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

http://www.regular-expressions.info


Letzte Ergänzung:

Angesichts der Tatsache, dass diese Frage immer noch viele Ansichten enthält, dachte ich, ich könnte ein Beispiel für die .replaceVerwendung mit einer Rückruffunktion hinzufügen . In diesem Fall vereinfacht dramatisch die Expression und bietet noch mehr Flexibilität, wie mit dem richtigen Kapitalisierung zu ersetzen oder beide ersetzen catund catsin einem Rutsch:

'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
Elias Van Ootegem
quelle
Ich denke, der zusätzliche interessante Teil sollte unten platziert werden. ps.: Ich habe gerade bemerkt, dass die Hälfte der ersten Zeile außerhalb des Bereichs liegt. Lassen Sie mich das beheben!
69

Übereinstimmung mit einem globalen regulären Ausdruck:

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

Zum Ersetzen einer einmaligen Verwendung:

var res = str.replace('abc', "");

Zum mehrfachen Ersetzen verwenden Sie:

var res = str.replace(/abc/g, "");
Indrajeet Singh
quelle
Für jemanden, der \ n ersetzen muss, können Sie dies wie replace(/\n/g, '<br/>')
folgt
58

Dies sind die gebräuchlichsten und lesbarsten Methoden.

var str = "Test abc test test abc test test test abc test test abc"

Methode 1:

str = str.replace(/abc/g, "replaced text");

Methode 2:

str = str.split("abc").join("replaced text");

Methode 3:

str = str.replace(new RegExp("abc", "g"), "replaced text");

Methode 4:

while(str.includes("abc")){
    str = str.replace("abc", "replaced text");
}

Ausgabe:

console.log(str);
// Test replaced text test test replaced text test test test replaced text test test replaced text
Adnan Toky
quelle
44
str = str.replace(/abc/g, '');

Oder probieren Sie die Funktion replaceAll 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, '');

EDIT: Klarstellung über ErsetzenAlle Verfügbarkeit

Die Methode 'replaceAll' wird dem Prototyp von String hinzugefügt. Dies bedeutet, dass es für alle Zeichenfolgenobjekte / 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'
SolutionYogi
quelle
2
Können Sie dort die Funktion replaceAll () für diejenigen umschreiben, die keinen Prototyp verwenden?
Klicken Sie auf Upvote
@Click Upvote .... Sie verwenden einen Prototyp, der Teil aller JS-Objekte ist. Ich denke, Sie denken an prototype.js die JS-Bibliothek.
Seth
Seth, eine kleine Korrektur. Wenn Sie einem Prototyp eine Methode hinzufügen, steht diese allen Objekten dieses Typs zur Verfügung. Die replceAll-Methode wurde dem String-Prototyp hinzugefügt und sollte für alle String-Objekte funktionieren.
SolutionYogi
@solutionyogi - Ja, ich habe schon einmal einen Prototyp (richtig) verwendet. Ich habe mich nur mit dem Kommentar des OP über "keinen Prototyp verwenden" befasst, von dem ich annahm, dass er Prototype.js bedeutet (vielleicht falsch?). Ich hätte "einen Prototyp" sagen sollen, als ich versuchte zu sagen, dass JavaScript-Objekte einen Prototyp haben. Daher verwendete das OP bereits "Prototypen", wenn auch auf "indirekte" Weise. Indirekt könnte der falsche Begriff sein, aber ich bin müde, also mea culpa.
Seth
41

Die Verwendung RegExpin JavaScript könnte den Job für Sie erledigen. Machen Sie einfach etwas wie den folgenden Code. Vergessen Sie nicht, /gworaufhin sich Global auszeichnet :

var str ="Test abc test test abc test test test abc test test abc";
str = str.replace(/abc/g, '');

Wenn Sie an eine Wiederverwendung denken, erstellen Sie eine Funktion, die dies für Sie erledigt. Dies wird jedoch nicht empfohlen, da es sich nur um eine einzeilige Funktion handelt. Wenn Sie diese Funktion jedoch häufig verwenden, können Sie Folgendes schreiben:

String.prototype.replaceAll = String.prototype.replaceAll || function(string, replaced) {
  return this.replace(new RegExp(string, 'g'), replaced);
};

und verwenden Sie es einfach immer und immer wieder in Ihrem Code wie unten:

var str ="Test abc test test abc test test test abc test test abc";
str = str.replaceAll('abc', '');

Wie ich bereits erwähnt habe, macht dies keinen großen Unterschied in Bezug auf die zu schreibenden Zeilen oder die Leistung. Nur das Zwischenspeichern der Funktion kann zu einer schnelleren Leistung bei langen Zeichenfolgen und auch zu einer bewährten Methode für DRY-Code führen, wenn Sie sie wiederverwenden möchten.

Alireza
quelle
40

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 habe versucht, über etwas Einfacheres nachzudenken, als den String-Prototyp zu modifizieren.

Emilio Grisolía
quelle
1
Einfach, leicht und wahrscheinlich die performanteste Option: nette Antwort.
Machineghost
Obwohl ich es nicht persönlich gemessen habe, ist Split / Join normalerweise eine sehr performante Lösung.
Machineghost
1
Es ist sogar in Chrom, 100% schneller auf Firefox und 50% langsamer auf IE ...: jsperf.com/replace-regex-split-join
Olivier
37

Verwenden Sie einen regulären Ausdruck:

str.replace(/abc/g, '');
Donnie DeBoer
quelle
32

Einfache Anführungszeichen ersetzen:

function JavaScriptEncode(text){
    text = text.replace(/'/g,'&apos;')
    // More encode here if required

    return text;
}
Chris Rosete
quelle
2
Wie kann ich die zweite Zeile ändern, um Zeichenfolgen zu ersetzen? Dies funktioniert nicht: text = text.replace ('hey', 'hallo'); Irgendeine Idee?
Stefan Đorđević
2
Klar Stefan, hier ist der Code ... text = text.replace (/ hey / g, 'hallo');
Chris Rosete
26

// Schleife, bis die Anzahl auf 0 kommt. ODER einfach kopieren / einfügen

    function replaceAll(find, replace, str) 
    {
      while( str.indexOf(find) > -1)
      {
        str = str.replace(find, replace);
      }
      return str;
    }
Raseela
quelle
23
Diese Methode ist gefährlich, verwenden Sie sie nicht. Wenn die Ersatzzeichenfolge das Suchschlüsselwort enthält, tritt eine Endlosschleife auf. Speichern Sie mindestens das Ergebnis von .indexOfin einer Variablen und verwenden Sie diese Variable als zweiten Parameter von .indexOf(minus Länge des Schlüsselworts plus Länge der Ersetzungszeichenfolge).
Rob W
Ich denke darüber nach, zuerst das Suchmuster durch ein unerwünschtes Unicode-Zeichen zu ersetzen. Wir sind sicher, dass es nicht in der Eingabezeichenfolge verwendet wird. Wie U + E000 im privaten Bereich. Und dann wieder zum Ziel zurücksetzen. Ich habe das hier gebaut. . Ich bin mir nicht sicher, ob das eine gute Idee ist.
Lux
26
str = str.replace(new RegExp("abc", 'g'), "");

funktionierte besser für mich als die obigen Antworten. So new RegExp("abc", 'g')wird ein RegExp erstellt, das mit allen Vorkommen ( 'g'Flag) des Textes ( "abc") übereinstimmt . Der zweite Teil wird ersetzt, in Ihrem Fall leere Zeichenfolge ( ""). strist die Zeichenfolge, und wir müssen sie überschreiben, da sie replace(...)nur das Ergebnis zurückgibt, aber nicht überschreibt. In einigen Fällen möchten Sie das möglicherweise verwenden.

csomakk
quelle
Während dieses Code-Snippet die Lösung sein kann, hilft das Hinzufügen einer Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen.
Yivi
Ja, du hast recht. hinzugefügt. bearbeitete es auch, um die ursprüngliche Frage zu beantworten :)
csomakk
Hinweis: g Flag in Regex bedeutet, dass es sich um ein globales Flag handelt, das mit allen Vorkommen
übereinstimmt
25

Dies ist die schnellste Version, die keine regulären Ausdrücke verwendet .

Überarbeitetes jsperf

replaceAll = function(string, omit, place, prevstring) {
  if (prevstring && string === prevstring)
    return string;
  prevstring = string.replace(omit, place);
  return replaceAll(prevstring, omit, place, string)
}

Es ist fast doppelt so schnell wie die Split-and-Join-Methode.

Wie in einem Kommentar hier ausgeführt, funktioniert dies nicht, wenn Ihre omitVariable placewie in: enthält replaceAll("string", "s", "ss"), da sie immer ein anderes Vorkommen des Wortes ersetzen kann.

Es gibt einen anderen jsperf mit Varianten meines rekursiven Ersatzes, die noch schneller gehen ( http://jsperf.com/replace-all-vs-split-join/12 )!

  • Update 27. Juli 2017: Es sieht so aus, als ob RegExp jetzt die schnellste Leistung im kürzlich veröffentlichten Chrome 59 hat.
Cole Lawrence
quelle
Ich habe deine Lösung geliebt ... Ich wünschte, ich könnte dir +10 geben, aber hier ist meine +1. Ich denke, Sie können den Index der ersetzten Unterzeichenfolge speichern und zum nächsten springen, wenn eine Übereinstimmung an einem niedrigeren Index gefunden wird, um dieses Endlosschleifenproblem zu vermeiden. Ich kann die Leistung nicht kommentieren, weil ich sie nicht getestet habe, aber das sind nur meine 2 Cent für dieses hervorragende Stück.
Fr0zenFyr
@ fr0zenfyr Wenn Sie überprüfen möchten, ob das Auslassen vorhanden ist (um eine Endlosschleife zu verhindern), können Sie eine Bedingung wie " if(place.replace(omit) === omit) {Keine Übereinstimmung" ausführen. Daher ist es sicher, "Ersetzen der Schleife" zu verwenden. Verwenden Sie } else {daher eine andere Methode wie "Teilen" und "Verbinden"}
Cole Lawrence
Hmm .. aber was bringt es, zwei Lösungen zu kombinieren? Ich bin sowieso kein Fan von Split / Join-Ansatz. Danke für den Rat.
Fr0zenFyr
@ Fr0zenFyr Ich glaube, der Zweck der Kombination der beiden Lösungen besteht darin, auf eine langsamere Methode zurückzugreifen, wenn Sie die schnellere nicht verwenden können (wenn die Schleife beispielsweise unendlich wäre). Es wäre also ein sicherer Schutz, die Funktionalität effizient, aber ohne die Möglichkeit eines Ausfalls sicherzustellen.
Cole Lawrence
@ Mama wie fehlerhaft?
SandRock
24

Performance

Heute 27.12.2019 führe ich Tests unter macOS v10.13.6 (High Sierra) für die ausgewählten Lösungen durch.

Schlussfolgerungen

  • Das str.replace(/abc/g, '');( C ) ist eine gute browserübergreifende schnelle Lösung für alle Zeichenfolgen.
  • Lösungen basierend auf split-join( A, B ) oder replace( C, D ) sind schnell
  • Lösungen, die auf while( E, F, G, H ) basieren , sind langsam - normalerweise ~ 4-mal langsamer für kleine Saiten und ungefähr ~ 3000-mal (!) Langsamer für lange Saiten
  • Die Wiederholungslösungen ( RA, RB ) sind langsam und funktionieren nicht für lange Zeichenfolgen

Ich erstelle auch meine eigene Lösung. Es sieht so aus, als ob es derzeit das kürzeste ist, das die Frage beantwortet:

str.split`abc`.join``

Einzelheiten

Die Tests wurden mit Chrome 79.0, Safari 13.0.4 und Firefox 71.0 (64 Bit) durchgeführt. Die Tests RAund RBverwenden Rekursion. Ergebnisse

Geben Sie hier die Bildbeschreibung ein

Kurze Zeichenfolge - 55 Zeichen

Sie können HIER Tests auf Ihrem Computer durchführen . Ergebnisse für Chrome:

Geben Sie hier die Bildbeschreibung ein

Lange Zeichenfolge: 275 000 Zeichen

Die rekursiven Lösungen RA und RB ergeben

RangeError: Maximale Aufrufstapelgröße überschritten

Für 1 Million Zeichen brechen sie sogar Chrome

Geben Sie hier die Bildbeschreibung ein

Ich versuche, Tests für 1 Million Zeichen für andere Lösungen durchzuführen, aber E, F, G, H benötigen so viel Zeit, dass der Browser mich auffordert, das Skript zu unterbrechen, sodass ich die Testzeichenfolge auf 275 KB Zeichen verkleinere. Sie können HIER Tests auf Ihrem Computer durchführen . Ergebnisse für Chrome

Geben Sie hier die Bildbeschreibung ein

In Tests verwendeter Code

Kamil Kiełczewski
quelle
1
Das ist eine verdammt ausführliche Antwort! Vielen Dank! Ich bin jedoch gespannt, warum die "neue RegExp (...)" - Syntax so viele Verbesserungen bringt.
Márk Gergely Dolinka
21

Wenn sich das, was Sie suchen möchten, bereits in einer Zeichenfolge befindet und Sie keinen Regex-Escaper zur Hand haben, können Sie join / split verwenden:

    function replaceMulti(haystack, needle, replacement)
    {
        return haystack.split(needle).join(replacement);
    }

    someString = 'the cat looks like a cat';
    console.log(replaceMulti(someString, 'cat', 'dog'));

Rakslice
quelle
Vielen Dank! Diese Lösung funktioniert perfekt für mein Problem :)
xero399
19
function replaceAll(str, find, replace) {
  var i = str.indexOf(find);
  if (i > -1){
    str = str.replace(find, replace); 
    i = i + replace.length;
    var st2 = str.substring(i);
    if(st2.indexOf(find) > -1){
      str = str.substring(0,i) + replaceAll(st2, find, replace);
    }       
  }
  return str;
}
Tim Rivoli
quelle
Ich frage mich, wie gut das funktioniert ... Teilzeichenfolge ist nativ oder geht über das Char-Array, um die neuen Zeichen zu erstellen.
mmm
16

Ich mag diese Methode (sie sieht etwas sauberer aus):

text = text.replace(new RegExp("cat","g"), "dog"); 
Owen
quelle
1
Okay, wie entkommen Sie der Zeichenfolge, um sie als Regex-Muster zu verwenden?
Rakslice
Ich nicht, ich benutze es nur für Klartext
Owen
15

Der einfachste Weg, dies ohne Verwendung von Regex zu tun, ist das Teilen und Verbinden wie im folgenden Code:

var str = "Test abc test test abc test test test abc test test abc";
str.split('abc').join('')
Sajadre
quelle
13
var str = "ff ff f f a de def";
str = str.replace(/f/g,'');
alert(str);

http://jsfiddle.net/ANHR9/

pkdkk
quelle
Was war der Sinn einer Geige, die nur das gleiche Javascript enthält
JGallardo
13
while (str.indexOf('abc') !== -1)
{
    str = str.replace('abc', '');
}
zdennis
quelle
13

Wenn die Zeichenfolge ein ähnliches Muster enthält abccc, können Sie Folgendes verwenden:

str.replace(/abc(\s|$)/g, "")
mostafa elmadany
quelle
13

Die vorherigen Antworten sind viel zu kompliziert. Verwenden Sie einfach die Ersetzungsfunktion wie folgt:

str.replace(/your_regex_pattern/g, replacement_string);

Beispiel:

var str = "Test abc test test abc test test test abc test test abc";

var res = str.replace(/[abc]+/g, "");

console.log(res);

Schwarz
quelle
10

Wenn Sie sicherstellen möchten, dass die gesuchte Zeichenfolge auch nach dem Ersetzen nicht vorhanden ist, müssen Sie eine Schleife verwenden.

Zum Beispiel:

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

Wenn Sie fertig sind, haben Sie immer noch 'test abc'!

Die einfachste Schleife, um dies zu lösen, wäre:

var str = 'test aabcbc';
while (str != str.replace(/abc/g, '')){
   str.replace(/abc/g, '');
}

Damit wird der Austausch jedoch für jeden Zyklus zweimal ausgeführt. Vielleicht (mit der Gefahr einer Ablehnung) kann dies zu einer etwas effizienteren, aber weniger lesbaren Form kombiniert werden:

var str = 'test aabcbc';
while (str != (str = str.replace(/abc/g, ''))){}
// alert(str); alerts 'test '!

Dies kann besonders nützlich sein, wenn Sie nach doppelten Zeichenfolgen suchen.
Zum Beispiel, wenn wir 'a ,,, b' haben und alle doppelten Kommas entfernen möchten.
[In diesem Fall könnte man .replace (/, + / g, ',') ausführen, aber irgendwann wird der reguläre Ausdruck komplex und langsam genug, um stattdessen eine Schleife zu erstellen.]

SamGoody
quelle
10

Obwohl die Leute die Verwendung von Regex erwähnt haben, gibt es einen besseren Ansatz, wenn Sie den Text unabhängig vom Fall des Textes ersetzen möchten. Wie Groß- oder Kleinbuchstaben. Verwenden Sie die folgende Syntax

//Consider below example
originalString.replace(/stringToBeReplaced/gi, '');

//Output will be all the occurrences removed irrespective of casing.

Das ausführliche Beispiel finden Sie hier .

Cheezy Code
quelle
von der Beispielseite: "/ toBeReplacedString / gi ist der reguläre Ausdruck, den Sie verwenden müssen. Hier steht g für globale Übereinstimmung und i für Groß- und Kleinschreibung. Standardmäßig wird bei Groß- und Kleinschreibung nicht
berücksichtigt
8

Sie können einfach die folgende Methode verwenden

/**
 * Replace all the occerencess of $find by $replace in $originalString
 * @param  {originalString} input - Raw string.
 * @param  {find} input - Target key word or regex that need to be replaced.
 * @param  {replace} input - Replacement key word
 * @return {String}       Output string
 */
function replaceAll(originalString, find, replace) {
  return originalString.replace(new RegExp(find, 'g'), replace);
};
tk_
quelle
7

Einfach hinzufügen /g

document.body.innerHTML = document.body.innerHTML.replace('hello', 'hi');

zu

// Replace 'hello' string with /hello/g regular expression.
document.body.innerHTML = document.body.innerHTML.replace(/hello/g, 'hi');

/g bedeutet global

Reza Fahmi
quelle