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 abc
in der obigen Zeichenfolge zu entfernen .
Wie kann ich alle Vorkommen ersetzen ?
javascript
string
replace
Klicken Sie auf Upvote
quelle
quelle
aba
inababa
durch ersetzenca
?caba
?abca
?cca
?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.replaceAll
ersetzt 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, wirdString.prototype.replaceAll
eine Ausnahme ausgelöst. “Antworten:
Hinweis: Verwenden Sie dies nicht in leistungskritischem Code.
Als Alternative zu regulären Ausdrücken für eine einfache Literalzeichenfolge können Sie verwenden
Das allgemeine Muster ist
Dies war in einigen Fällen schneller als die Verwendung
replaceAll
und 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.
quelle
String.prototype.replaceAll = function(f,r){return this.split(f).join(r);}
. Verwendung:"My string".replaceAll('st', '');
produziert "Mein Ring"replaceAll
einfach 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.Als Antwort auf den Kommentar:
Als Antwort auf den Kommentar von Click Upvote können Sie ihn noch weiter vereinfachen:
Hinweis: Reguläre Ausdrücke enthalten Sonderzeichen (Metazeichen). Daher ist es gefährlich, ein Argument in der
find
obigen 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):Um die
replaceAll()
oben genannte Funktion sicherer zu machen , kann sie wie folgt geändert werden, wenn Sie auch Folgendes angebenescapeRegExp
:quelle
function replaceAll(find, replace,str) { var re = new RegExp(find, 'g'); str = str.replace(re, replace); return str; }
replaceAll
Implementierung ist, dass sie nicht funktioniert, wenn siefind
Metazeichen enthält.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
String
eingebauten Prototyp.Implementierung auf Basis regulärer Ausdrücke
Split and Join (funktionale) Implementierung
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
search
bestimmte 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:Wir könnten
escapeRegExp
innerhalb unsererString.prototype.replaceAll
Implementierung 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).quelle
Die Verwendung eines regulären Ausdrucks mit
g
gesetztem Flag ersetzt alle:Siehe auch hier
quelle
var sourceText
die Anzahl der Instanzen (numOfInstances
) mitsubstring
oder teilen und die Länge (unter anderem) vonthatWhichYouWantToReplace
dofor (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/g
so einfach und wahrscheinlich leistungsfähiger ist.Hier ist eine String-Prototyp-Funktion, die auf der akzeptierten Antwort basiert:
BEARBEITEN
Wenn Ihr
find
Testament Sonderzeichen enthält, müssen Sie ihnen entkommen:Geige: http://jsfiddle.net/cdbzL/
quelle
find
Zeichen wie.
oder enthält$
, die in Regex eine besondere Bedeutung haben?var str = this
einen zweiten Verweis auf die unveränderliche Zeichenfolge, auf die diereplace
Methode 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 schreibensomeStrVar.replaceAll('o', '0');
undsomeStrVar
werden geändert. Stattdessen müssen SiesomeStrVar = 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;
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
)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 dencool-cat
folgenden zu vermeiden :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!
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:
Die Ausgabe entspricht der akzeptierten Antwort, verwendet jedoch den Ausdruck / cat / g für diese Zeichenfolge:
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:
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
.replace
Verwendung 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 ersetzencat
undcats
in einem Rutsch:quelle
Übereinstimmung mit einem globalen regulären Ausdruck:
quelle
Zum Ersetzen einer einmaligen Verwendung:
Zum mehrfachen Ersetzen verwenden Sie:
quelle
replace(/\n/g, '<br/>')
Dies sind die gebräuchlichsten und lesbarsten Methoden.
Methode 1:
Methode 2:
Methode 3:
Methode 4:
Ausgabe:
quelle
Oder probieren Sie die Funktion replaceAll von hier aus:
Was sind nützliche JavaScript-Methoden, die integrierte Objekte erweitern?
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
quelle
Die Verwendung
RegExp
in JavaScript könnte den Job für Sie erledigen. Machen Sie einfach etwas wie den folgenden Code. Vergessen Sie nicht,/g
woraufhin sich Global auszeichnet :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:
und verwenden Sie es einfach immer und immer wieder in Ihrem Code wie unten:
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.
quelle
Angenommen, Sie möchten alle 'abc' durch 'x' ersetzen:
Ich habe versucht, über etwas Einfacheres nachzudenken, als den String-Prototyp zu modifizieren.
quelle
Verwenden Sie einen regulären Ausdruck:
quelle
Einfache Anführungszeichen ersetzen:
quelle
// Schleife, bis die Anzahl auf 0 kommt. ODER einfach kopieren / einfügen
quelle
.indexOf
in einer Variablen und verwenden Sie diese Variable als zweiten Parameter von.indexOf
(minus Länge des Schlüsselworts plus Länge der Ersetzungszeichenfolge).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 (""
).str
ist die Zeichenfolge, und wir müssen sie überschreiben, da siereplace(...)
nur das Ergebnis zurückgibt, aber nicht überschreibt. In einigen Fällen möchten Sie das möglicherweise verwenden.quelle
Dies ist die schnellste Version, die keine regulären Ausdrücke verwendet .
Überarbeitetes jsperf
Es ist fast doppelt so schnell wie die Split-and-Join-Methode.
Wie in einem Kommentar hier ausgeführt, funktioniert dies nicht, wenn Ihre
omit
Variableplace
wie in: enthältreplaceAll("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 )!
quelle
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"}
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
str.replace(/abc/g, '');
( C ) ist eine gute browserübergreifende schnelle Lösung für alle Zeichenfolgen.split-join
( A, B ) oderreplace
( C, D ) sind schnellwhile
( E, F, G, H ) basieren , sind langsam - normalerweise ~ 4-mal langsamer für kleine Saiten und ungefähr ~ 3000-mal (!) Langsamer für lange SaitenIch erstelle auch meine eigene Lösung. Es sieht so aus, als ob es derzeit das kürzeste ist, das die Frage beantwortet:
Code-Snippet anzeigen
Einzelheiten
Die Tests wurden mit Chrome 79.0, Safari 13.0.4 und Firefox 71.0 (64 Bit) durchgeführt. Die Tests
RA
undRB
verwenden Rekursion. ErgebnisseKurze Zeichenfolge - 55 Zeichen
Sie können HIER Tests auf Ihrem Computer durchführen . Ergebnisse für Chrome:
Lange Zeichenfolge: 275 000 Zeichen
Die rekursiven Lösungen RA und RB ergeben
Für 1 Million Zeichen brechen sie sogar Chrome
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
In Tests verwendeter Code
Code-Snippet anzeigen
quelle
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:
quelle
quelle
Ich mag diese Methode (sie sieht etwas sauberer aus):
quelle
Der einfachste Weg, dies ohne Verwendung von Regex zu tun, ist das Teilen und Verbinden wie im folgenden Code:
quelle
http://jsfiddle.net/ANHR9/
quelle
quelle
Wenn die Zeichenfolge ein ähnliches Muster enthält
abccc
, können Sie Folgendes verwenden:quelle
Die vorherigen Antworten sind viel zu kompliziert. Verwenden Sie einfach die Ersetzungsfunktion wie folgt:
Beispiel:
quelle
Wenn Sie sicherstellen möchten, dass die gesuchte Zeichenfolge auch nach dem Ersetzen nicht vorhanden ist, müssen Sie eine Schleife verwenden.
Zum Beispiel:
Wenn Sie fertig sind, haben Sie immer noch 'test abc'!
Die einfachste Schleife, um dies zu lösen, wäre:
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:
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.]
quelle
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
Das ausführliche Beispiel finden Sie hier .
quelle
Sie können einfach die folgende Methode verwenden
quelle
Einfach hinzufügen
/g
zu
/g
bedeutet globalquelle