Come sostituire tutte le occorrenze di una stringa?


4383

Ho questa stringa:

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

fare:

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

sembra rimuovere solo la prima occorrenza di abcnella stringa sopra.

Come posso sostituirne tutte le occorrenze?


5
Quando si sostituiscono tutte le occorrenze di abain ababacon ca, quale risultato ti aspetti? caba? abca? cca?
reinierpost,

String.prototype.replaceAll()spedito in Safari 13.1 e ora in Firefox Nightly e Chrome Dev e Canary e verrà spedito in Firefox 77 e Chrome 85. Non è ancora documentato in MDN, ma github.com/tc39/proposal-string-replaceall#high-level-api ha una spiegazione: "Se searchValue è una stringa, String.prototype.replaceAllsostituisce tutte le occorrenze di searchValue (come se .split(searchValue).join(replaceValue)fosse stata usata un'espressione regolare globale e correttamente sfuggita). Se searchValue è un'espressione regolare non globale, String.prototype.replaceAllgenera un'eccezione ”
sideshowbarker

Risposte:


1612

Nota: non utilizzarlo nel codice critico per le prestazioni.

In alternativa alle espressioni regolari per una semplice stringa letterale, è possibile utilizzare

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

Lo schema generale è

str.split(search).join(replacement)

In alcuni casi questo era più veloce dell'uso replaceAll e di un'espressione regolare, ma non sembra più essere il caso nei browser moderni.

Prova delle prestazioni: https://jsperf.com/replace-all-vs-split-join

Conclusione: se si dispone di un caso d'uso critico per le prestazioni (ad es. Elaborazione di centinaia di stringhe), utilizzare il metodo Regexp. Ma per i casi d'uso più tipici, vale la pena non doversi preoccupare di caratteri speciali.


147
Mi ha sorpreso, poiché mi sarei aspettato che questo metodo allocasse più oggetti, creasse più immondizia, e quindi impiegasse più tempo, ma quando ho effettivamente testato in un browser questo metodo era costantemente circa il 20% più veloce della risposta accettata. I risultati possono variare, ovviamente.
MgSam,

42
Ero curioso di me stesso e ho creato questo: jsperf.com/replace-all-vs-split-join . Sembra che v8 sia semplicemente pazzo a dividere / unire array rispetto ad altri motori javascript.
fabi,

8
Molto bello - ti salva anche dalla possibilità di RegExps cattivi quando passi caratteri speciali. Sto aggiungendo un flag generico per "trova questo e sostituiscilo" in una proprietà dell'oggetto, ma ero preoccupato se avessi bisogno di sostituire "." o "}" e ho dimenticato che stavo usando RegEx 3 mesi dopo!
tobriand,

9
E come String.prototype: String.prototype.replaceAll = function(f,r){return this.split(f).join(r);}. Utilizzo: "My string".replaceAll('st', '');produce "Il mio anello"
MacroMan,

8
Non vedo un motivo per cui l'avvertimento non lo utilizza in produzione. Non è più un hack che sfuggire a una regex solo perché vuoi sostituire più occorrenze, ma non hai bisogno di una regex in primo luogo. Basta avvolgere questo cosiddetto "hack" in una bella replaceAllfunzione e diventa leggibile come qualsiasi altra cosa. Poiché le prestazioni non sono male, non c'è motivo di evitare questa soluzione.
Youen

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

In risposta al commento:

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

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

In risposta al commento di Click Upvote , potresti semplificarlo ancora di più:

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

Nota: le espressioni regolari contengono caratteri speciali (meta) e come tali è pericoloso passare ciecamente un argomento nella findfunzione sopra senza pre-elaborarlo per sfuggire a quei caratteri. Questo argomento è trattato nel Mozilla Developer Network 's Guida JavaScript su espressioni regolari , in cui essi presentano la seguente funzione di utilità (che ha cambiato almeno due volte da quando questa risposta è stato originariamente scritto, quindi assicuratevi di controllare il sito MDN per i potenziali aggiornamenti):

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

Quindi, al fine di rendere la replaceAll()funzione sopra più sicura, potrebbe essere modificata come segue se si include anche escapeRegExp:

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

4
Le espressioni regolari sono l'unico modo per realizzare questo "out of the box" senza implementare il proprio metodo "replaceAll". Non sto suggerendo il loro uso solo per il gusto di usarli.
Sean Bright,

10
Questa è la mia funzione da questo commento: function replaceAll(find, replace,str) { var re = new RegExp(find, 'g'); str = str.replace(re, replace); return str; }
Fai clic su Voto

47
Il principale avvertimento replaceAlldell'implementazione è che non funzionerà se findcontiene metacaratteri.
Martin Ender,

1
@SeanBright hai ragione. Ho usato il tuo javascript in un codice php, quindi ho dovuto aggiungere una barra rovesciata in più per fuggire. Al violino il tuo codice è perfetto. Avrei dovuto controllare. Scuse jsfiddle.net/7y19xyq8
Onimusha


2437

Per completezza, sono arrivato a pensare a quale metodo dovrei usare per farlo. Esistono sostanzialmente due modi per farlo, come suggerito dalle altre risposte in questa pagina.

Nota: in generale, l'estensione dei prototipi integrati in JavaScript non è generalmente consigliata. Sto fornendo come estensioni il prototipo String semplicemente a scopo illustrativo, mostrando diverse implementazioni di un ipotetico metodo standard sul Stringprototipo incorporato.


Implementazione basata su espressioni regolari

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

Implementazione divisa e congiunta (funzionale)

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

Non sapendo troppo di come le espressioni regolari lavorino dietro le quinte in termini di efficienza, tendevo a inclinarmi verso la divisione e ad unire l'implementazione in passato senza pensare alle prestazioni. Quando mi chiedevo quale fosse più efficiente e con quale margine, l'ho usato come scusa per scoprirlo.

Sulla mia macchina Chrome Windows 8, l'implementazione basata su espressioni regolari è la più veloce , con il implementazione divisa e di join più lenta del 53% . Significa che le espressioni regolari sono due volte più veloci per l'input lorem ipsum che ho usato.

Dai un'occhiata a questo benchmark che esegue queste due implementazioni l'una contro l'altra.


Come notato nel commento qui sotto di @ThomasLeduc e altri, potrebbe esserci un problema con l'implementazione basata su espressioni regolari se searchcontiene determinati caratteri che sono riservati come caratteri speciali nelle espressioni regolari . L'implementazione presuppone che il chiamante sfuggirà anticipatamente alla stringa o passerà solo le stringhe che sono prive dei caratteri nella tabella nelle espressioni regolari (MDN).

MDN fornisce anche un'implementazione per sfuggire alle nostre stringhe. Sarebbe bello se anche questo fosse standardizzato come RegExp.escape(str), ma purtroppo non esiste:

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

Potremmo chiamare escapeRegExpnella nostra String.prototype.replaceAllimplementazione, tuttavia, non sono sicuro di quanto ciò influirà sulle prestazioni (potenzialmente anche per le stringhe per le quali non è necessaria la fuga, come tutte le stringhe alfanumeriche).


8
Su Android 4.1 il metodo regexp è più veloce del 15%, ma non stai sfuggendo all'espressione da cercare, quindi questo benchmark è incompleto.
Andreszs,

33
C'è un problema con questa soluzione, se la stringa di ricerca sembra contenere caratteri speciali di un'espressione regexp, verranno interpretati. Raccomando la risposta @Sandy Unitedwolf.
Thomas Leduc,

2
Il primo lo farà: 'bla.bla'.replaceAll ('. ',' _ '); "_______". Il secondo farà "bla_bla", che è più in generale quello che vuoi fare.
RobKohr,

1
@ThomasLeduc sembra che il problema che hai citato possa essere risolto con lodash => lodash.com/docs/4.17.5#escapeRegExp
Matthew Beck

1
Lasciare questo qui per i futuri spettatori che si chiedono anche perché l'estensione dell'oggetto nativo sia una cattiva idea: stackoverflow.com/questions/14034180/…
Ben Cooper

692

L'uso di un'espressione regolare con il gflag impostato sostituirà tutto:

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

Vedi anche qui


15
Un po 'sciocco, penso, ma la regex globale di JS è l'unico modo per fare più rimpiazzi.
Mike,

5
bene tecnicamente puoi ripetere il var sourceTextconteggio del numero di istanze ( numOfInstances) usando substringo dividere e contare la lunghezza (tra le altre strategie) di thatWhichYouWantToReplacepoi fare for (var i = 0; i < numOfInstances; i++){ sourceText = sourceText.replace('thatWhichYouWantToReplace', '');} o ancora più semplicemente usare un ciclo while ( while sourceText.indexOf(thatWhichYouWantToReplace > -1){ sourceText = sourceText.replace(...)) ma non vedo perché vorresti farlo in questo modo quando si usa /gè così facile e probabilmente più performante.
Zargold

@Zargold Vorresti fare un ciclo per assicurarti che anche dopo la sostituzione hai sostituito tutte le istanze, che è un gotcha abbastanza comune. Vedere la mia risposta qui sotto stackoverflow.com/a/26089052/87520
SamGoody

109

Ecco una funzione di prototipo di stringa basata sulla risposta accettata:

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

MODIFICARE

Se findconterrai caratteri speciali, dovrai fuggire:

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

Fiddle: http://jsfiddle.net/cdbzL/


5
Ma cosa succede se findcontiene caratteri simili .o $che hanno un significato speciale in regex?
callum,

1
@callum In tal caso dovresti uscire dalla tua variabile find (vedi modifica sopra).
Gesù,


jesal, questa è una soluzione meravigliosa a un problema di sostituzione di stringhe che ho riscontrato e apparentemente supera l '"immutabilità" delle stringhe in JavaScript. Potresti tu o qualcun altro spiegare come questa funzione del prototipo prevale sull'immutabilità delle stringhe? Questo fa di lavoro; Voglio solo capire questa domanda ausiliaria che pone.
Tom,

1
@ Tom: non supera affatto l'immutabilità: var str = thiscrea un secondo riferimento alla stringa immutabile, a cui replaceviene applicato il metodo, che a sua volta restituisce una nuova stringa immutabile . queste funzioni del prototipo restituiscono una nuova stringa immutabile, in caso contrario, saresti in grado di scrivere someStrVar.replaceAll('o', '0');e someStrVarverrebbero modificati. Invece, devi scrivere someStrVar = someStrVar.replaceAll('o', '0');<- reassign per impostare var per contenere la nuova stringa immutabile . non c'è modo di aggirare questo. Prova in console:x = 'foobar'; x.replaceAll('o', '0'); x;
Elias Van Ootegem,

87

Aggiornare:

È un po 'tardi per un aggiornamento, ma dal momento che mi sono appena imbattuto in questa domanda e ho notato che la mia risposta precedente non è soddisfacente. Poiché la domanda riguardava la sostituzione di una sola parola, è incredibile che nessuno abbia pensato di usare i confini delle parole ( \b)

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

Questo è un regex semplice che nella maggior parte dei casi evita di sostituire parti di parole. Tuttavia, un trattino -è ancora considerato un limite di parole. Quindi i condizionali possono essere usati in questo caso per evitare di sostituire stringhe come 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"

fondamentalmente, questa domanda è la stessa della domanda qui: Javascript sostituisce "'" con "' '"

@ Mike, controlla la risposta che ho dato lì ... regexp non è l'unico modo per sostituire più occorrenze di un abbonamento, tutt'altro. Pensa flessibile, pensa diviso!

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

In alternativa, per impedire la sostituzione di parti di parole, cosa che farà anche la risposta approvata! Puoi aggirare questo problema usando espressioni regolari che, ammetto, sono un po 'più complesse e, come risultato, anche un po' più lente:

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

L'output è uguale alla risposta accettata, tuttavia, usando l'espressione / cat / g su questa stringa:

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" ?? 

Oops, questo probabilmente non è quello che vuoi. Cos'è allora? IMHO, una regex che sostituisce solo "gatto" in modo condizionale. (cioè non fa parte di una parola), in questo modo:

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"

Suppongo che questo soddisfi le tue esigenze. Ovviamente non è completamente impermeabile, ma dovrebbe essere sufficiente per iniziare. Consiglierei di leggere qualcosa in più su queste pagine. Ciò si rivelerà utile nel perfezionare questa espressione per soddisfare le tue esigenze specifiche.

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

http://www.regular-expressions.info


Aggiunta finale:

Dato che questa domanda ha ancora molte visualizzazioni, ho pensato di aggiungere un esempio di .replaceusato con una funzione di callback. In questo caso, semplifica notevolmente l'espressione e offre una flessibilità ancora maggiore, come la sostituzione con la corretta capitalizzazione o la sostituzione di entrambi cate catsin una volta sola:

'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

Penso che la parte interessante aggiuntiva dovrebbe essere messa in fondo. ps .: Ho notato proprio ora che la metà della prima riga è fuori dall'area, permettimi di risolvere il problema!

69

Abbina un'espressione regolare globale:

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

60

Per sostituire un singolo utilizzo:

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

Per sostituire più volte utilizzare:

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

per qualcuno è necessario sostituire \ n, puoi farlo come replace(/\n/g, '<br/>')
segue

58

Questi sono i metodi più comuni e leggibili.

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

Metodo 1:

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

Metodo 2:

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

Metodo 3:

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

Metodo 4:

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

Produzione:

console.log(str);
// Test replaced text test test replaced text test test test replaced text test test replaced text

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

Oppure prova la funzione di sostituzione Tutto da qui:

Quali sono utili metodi JavaScript che estendono gli oggetti incorporati?

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

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

EDIT: chiarimenti sulla sostituzione di tutta la disponibilità

Il metodo 'replaceAll' viene aggiunto al prototipo di String. Ciò significa che sarà disponibile per tutti gli oggetti stringa / letterali.

Per esempio

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

2
Puoi riscrivere la funzione replaceAll () lì per coloro che non usano il prototipo?
Fai clic su Aggiorna il

@Click Upvote .... stai usando il prototipo, fa parte di tutti gli oggetti JS. Penso che stai pensando a prototype.js la libreria JS.
seth,

seth, una piccola correzione. Se aggiungi il metodo a un prototipo, è disponibile per tutti gli oggetti di quel tipo. Il metodo replceAll è stato aggiunto al prototipo String e dovrebbe funzionare per tutti gli oggetti stringa.
SolutionYogi,

@solutionyogi - Sì, ho usato il prototipo (correttamente) prima. Stavo solo affrontando il commento del PO su "non usare il prototipo" che supponevo volesse dire Prototype.js (forse in modo errato?). Avrei dovuto dire "un prototipo" mentre stavo cercando di dire che gli oggetti JavaScript hanno un prototipo. Pertanto, l'OP stava già "utilizzando il prototipo", sebbene in modo "indiretto". Indiretto potrebbe essere il termine sbagliato da usare qui, ma sono stanco quindi mea culpa.
seth,

41

L'utilizzo RegExpin JavaScript potrebbe fare al caso tuo, semplicemente fai qualcosa come il codice qui sotto, non dimenticare il /gdopo che spicca per il globale :

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

Se pensi al riutilizzo, crea una funzione per farlo per te, ma non è consigliabile in quanto è solo una funzione di linea, ma di nuovo se la usi intensamente, puoi scrivere qualcosa del genere:

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

e semplicemente usalo nel tuo codice più e più volte come di seguito:

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

Ma come accennato in precedenza, non farà un'enorme differenza in termini di righe da scrivere o prestazioni, solo la memorizzazione nella cache della funzione può influire su prestazioni più veloci su stringhe lunghe e anche una buona pratica del codice DRY se si desidera riutilizzare.


40

Supponiamo che tu voglia sostituire tutto "abc" con "x":

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

Stavo cercando di pensare a qualcosa di più semplice della modifica del prototipo di stringa.


1
Semplice, facile e probabilmente l'opzione più performante: bella risposta.
machineghost,

In realtà, anche se non l'ho metricato personalmente, dividere / unire è di solito una soluzione molto performante.
machineghost

1
è persino in Chrome, 100% più veloce su Firefox e 50% più lento su IE ...: jsperf.com/replace-regex-split-join
Olivier


32

Sostituzione di virgolette singole:

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

    return text;
}

2
Come posso cambiare la seconda riga per sostituire le stringhe? Questo non funziona: text = text.replace ('hey', 'hello'); Qualche idea?
Stefan Đorđević,

2
Certo Stefan, ecco il codice ... text = text.replace (/ hey / g, 'hello');
Chris Rosete,

26

// esegue il ciclo fino a quando le occorrenze di numeri arrivano a 0. O semplicemente copia / incolla

    function replaceAll(find, replace, str) 
    {
      while( str.indexOf(find) > -1)
      {
        str = str.replace(find, replace);
      }
      return str;
    }

23
Questo metodo è pericoloso, non usarlo. Se la stringa di sostituzione contiene la parola chiave di ricerca, si verificherà un ciclo infinito. Almeno, archivia il risultato .indexOfin una variabile e usa questa variabile come secondo parametro di .indexOf(meno lunghezza della parola chiave, più lunghezza della stringa di sostituzione).
Rob W,

Sto pensando di sostituire prima il modello di ricerca con un carattere unicode weired, di questo siamo sicuri che non sia usato nella stringa di input. Come U + E000 nell'area privata. E poi sostituiscilo al bersaglio. L'ho costruito qui. . Non sono sicuro che sia una buona idea.
Lux,

26
str = str.replace(new RegExp("abc", 'g'), "");

ha funzionato meglio per me rispetto alle risposte di cui sopra. quindi new RegExp("abc", 'g')crea un RegExp che corrisponde a tutte le occorrenze ( 'g'flag) del testo ( "abc"). La seconda parte è ciò che viene sostituito, nel tuo caso stringa vuota ( ""). strè la stringa e dobbiamo sostituirla, poiché replace(...)restituisce solo il risultato, ma non le sostituisce. In alcuni casi potresti volerlo usare.


Sebbene questo frammento di codice possa essere la soluzione, inclusa una spiegazione aiuta davvero a migliorare la qualità del tuo post. Ricorda che in futuro stai rispondendo alla domanda dei lettori e che queste persone potrebbero non conoscere i motivi del tuo suggerimento sul codice.
yivi,

Si hai ragione. aggiunto. anche modificato per rispondere alla domanda originale :)
csomakk

Nota: g flag in regex significa che è la bandiera globale che corrisponderà a tutte le occorrenze
firstpostcommenter

25

Questa è la versione più veloce che non usa espressioni regolari .

Revisionato jsperf

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

Sono quasi due volte più veloce del metodo split e join.

Come sottolineato in un commento qui, questo non funzionerà se la tua omitvariabile contiene place, come in:replaceAll("string", "s", "ss") perché sarà sempre in grado di sostituire un'altra occorrenza della parola.

C'è un altro jsperf con varianti sul mio sostituto ricorsivo che va ancora più veloce ( http://jsperf.com/replace-all-vs-split-join/12 )!

  • Aggiornamento del 27 luglio 2017: sembra che RegExp abbia ora le prestazioni più veloci nel Chrome 59 recentemente rilasciato.

Ho adorato la tua soluzione ... Vorrei poterti dare +10 ma ecco il mio +1. Penso che puoi memorizzare l'indice della sottostringa che è stata sostituita e passare alla successiva se viene trovata una corrispondenza con un indice inferiore per evitare quel problema di loop infinito. Non posso commentare la performance perché non l'ho provata ma sono solo i miei 2 centesimi su questo pezzo di eccellenza.
Fr0zen,

@ fr0zenfyr se vuoi verificare se è presente l'omissione (per evitare un ciclo infinito) potresti fare un condizionale come if(place.replace(omit) === omit) { No match, quindi è sicuro usare sostituisci loop } else {match quindi usa un metodo diverso come split e join}
Cole Lawrence

Hmm .. ma qual è il punto che combina due soluzioni? Comunque non sono un fan dell'approccio split / join .. grazie per il consiglio ..
Fr0zenFir

@ Fr0zenFyr Credo che lo scopo di combinare le due soluzioni sarebbe di ripiegare su un metodo più lento se non è possibile utilizzare quello più veloce (ad esempio quando il ciclo sarebbe infinito). Quindi sarebbe una protezione sicura garantire funzionalità con efficienza, ma senza possibilità di guasto.
Cole Lawrence,

@momomo quanto imperfetto?
SandRock

24

Prestazione

Oggi 27.12.2019 eseguo test su macOS v10.13.6 (High Sierra) per le soluzioni scelte.

conclusioni

  • Il str.replace(/abc/g, '');( C ) è una buona soluzione veloce cross-browser per tutte le stringhe.
  • Soluzioni basate su split-join( A, B ) o replace( C, D ) sono veloci
  • Soluzioni basate su while( E, F, G, H ) sono lente - di solito ~ 4 volte più lente per stringhe piccole e circa ~ 3000 volte (!) Più lente per stringhe lunghe
  • Le soluzioni di ricorrenza ( RA, RB ) sono lente e non funzionano per stringhe lunghe

Creo anche la mia soluzione. Sembra che attualmente sia il più corto a fare il lavoro della domanda:

str.split`abc`.join``

Dettagli

I test sono stati eseguiti su Chrome 79.0, Safari 13.0.4 e Firefox 71.0 (64 bit). I testRA e RButilizzano la ricorsione. risultati

Inserisci qui la descrizione dell'immagine

Stringa corta - 55 caratteri

Puoi eseguire i test sul tuo computer QUI . Risultati per Chrome:

Inserisci qui la descrizione dell'immagine

Stringa lunga: 275000 caratteri

Le soluzioni ricorsive RA e RB danno

RangeError: dimensione massima dello stack di chiamate superata

Per i personaggi da 1 milione, rompono persino Chrome

inserisci qui la descrizione dell'immagine

Cerco di eseguire test per caratteri 1M per altre soluzioni, ma E, F, G, H impiegano così tanto tempo che il browser mi chiede di interrompere lo script, quindi restringo la stringa di test a 275K caratteri. Puoi eseguire i test sul tuo computer QUI . Risultati per Chrome

inserisci qui la descrizione dell'immagine

Codice utilizzato nei test


1
Ora questa è una risposta davvero incredibile! Grazie mille! Tuttavia, ciò di cui sono curioso è perché la sintassi "new RegExp (...)" offre un notevole miglioramento.
Márk Gergely Dolinka,

21

Se quello che vuoi trovare è già in una stringa e non hai a portata di mano un'escape regex, puoi usare join / split:

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

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


Grazie! Questa soluzione funziona perfettamente per il mio problema :)
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;
}

Mi chiedo quanto bene funzioni ... la sottostringa è nativa o cammina sull'array di caratteri per creare i nuovi personaggi.
mmm

16

Mi piace questo metodo (sembra un po 'più pulito):

text = text.replace(new RegExp("cat","g"), "dog"); 

1
Va bene, come si fa a sfuggire alla stringa per usarla come modello regex?
rakslice,

Non lo uso solo per il semplice testo
Owen

15

Il modo più semplice per farlo senza usare regex è diviso e unisci come il codice qui:

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


13
while (str.indexOf('abc') !== -1)
{
    str = str.replace('abc', '');
}

13

Se la stringa contiene un modello simile abccc, puoi usare questo:

str.replace(/abc(\s|$)/g, "")

13

Le risposte precedenti sono troppo complicate. Basta usare la funzione di sostituzione in questo modo:

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

Esempio:

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

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

console.log(res);


10

Se stai cercando di assicurarti che la stringa che stai cercando non esista anche dopo la sostituzione, devi usare un loop.

Per esempio:

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

Al termine, avrai ancora "test abc"!

Il ciclo più semplice per risolvere questo sarebbe:

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

Ma questo esegue la sostituzione due volte per ogni ciclo. Forse (a rischio di essere votato verso il basso) che può essere combinato per una forma leggermente più efficiente ma meno leggibile:

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

Ciò può essere particolarmente utile quando si cercano stringhe duplicate.
Ad esempio, se abbiamo "a ,,, b" e desideriamo rimuovere tutte le virgole duplicate.
[In tal caso, si potrebbe fare .replace (/, + / g, ','), ma a un certo punto la regex diventa piuttosto complessa e abbastanza lenta da eseguire il loop.]


10

Sebbene le persone abbiano menzionato l'uso di regex, c'è un approccio migliore se si desidera sostituire il testo indipendentemente dal caso del testo. Come maiuscolo o minuscolo. Usa la sintassi seguente

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

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

Puoi fare riferimento all'esempio dettagliato qui .


dal sito di esempio: "/ toBeReplacedString / gi è la regex che devi usare. Qui g rappresenta la corrispondenza globale e i rappresenta la distinzione tra maiuscole e minuscole. Per impostazione predefinita regex fa distinzione tra maiuscole e minuscole"
alikuli,

8

Puoi semplicemente usare il metodo seguente

/**
 * 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);
};

7

Basta aggiungere /g

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

per

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

/g significa globale

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.