Domanda Come sostituire tutte le occorrenze di una stringa in JavaScript?


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 abc nella stringa sopra. Come posso sostituire tutti occorrenze di esso?


3160
2017-07-17 17:53


origine


risposte:


Per completezza, ho avuto modo di pensare a quale metodo dovrei usare per farlo. Ci sono fondamentalmente due modi per farlo come suggerito dalle altre risposte in questa pagina.

Nota: In generale, l'estensione dei prototipi incorporati in JavaScript non è generalmente raccomandata. Sto fornendo come estensioni sul prototipo di String semplicemente per scopi illustrativi, mostrando diverse implementazioni di un ipotetico metodo standard su String prototipo integrato.


Esecuzione basata su espressioni regolari

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

Implementazione divisa e join (funzionale)

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

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

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

Controlla questo segno di riferimento eseguendo queste due implementazioni l'una contro l'altra.


Come notato nel commento seguente di @ThomasLeduc e altri, potrebbe esserci un problema con l'implementazione basata su espressioni regolari, se search contiene determinati caratteri che sono riservati come caratteri speciali nelle espressioni regolari. L'implementazione presuppone che il chiamante sfugga alla stringa in anticipo o passerà solo le stringhe senza i caratteri nella tabella 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 ahimè, non esiste:

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

Potremmo chiamare escapeRegExp dentro il nostro String.prototype.replaceAll implementazione, tuttavia, non sono sicuro di quanto questo influenzi le prestazioni (potenzialmente anche per le stringhe per le quali non è necessaria la fuga, come tutte le stringhe alfanumeriche).


1625
2017-07-12 01:46



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

In risposta al commento:

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

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

In risposta a Clicca su VotoIl commento, 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 tale è pericoloso passare ciecamente un argomento nel find funzione sopra senza pre-elaborazione per sfuggire a quei personaggi. Questo è coperto nel Mozilla Developer Network'S Guida JavaScript su espressioni regolari, dove presentano la seguente funzione di utilità:

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

Quindi, al fine di rendere il replaceAll() funzione sopra più sicura, potrebbe essere modificata alla seguente se si include anche escapeRegExp:

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

3585
2017-07-17 17:54



Nota: non usare questo nel codice reale.

In alternativa alle espressioni regolari per una semplice stringa letterale, puoi usare

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 un'espressione regolare, ma non sembra più il caso nei browser moderni. Quindi, questo dovrebbe essere usato solo come un trucco rapido per evitare di dover sfuggire all'espressione regolare, non nel codice reale.


1193
2017-07-17 20:29



Usando un'espressione regolare con il g il flag set 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


505
2018-05-06 23:18



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 tuo find conterrà caratteri speciali, quindi dovrai sfuggirli:

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

Violino: http://jsfiddle.net/cdbzL/


90
2018-02-11 23:03



Aggiornare:

È un po 'tardi per un aggiornamento, ma da quando mi sono imbattuto in questa domanda e ho notato che la mia risposta precedente non è una di cui sono felice. Poiché la domanda riguardava la sostituzione di una singola parola, è incredibile che nessuno pensasse di usare i limiti delle parole (\b)

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

Questa è una semplice regex che evita di sostituire parti di parole nella maggior parte dei casi. Tuttavia, un trattino - è ancora considerato un confine 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"

in fondo, 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 subsrting, lontano da esso. Pensa flessibile, pensa dividi!

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

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

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

Oso davvero, questo probabilmente non è quello che vuoi. Cos'è, allora? IMHO, una regex che sostituisce solo "gatto" in modo condizionale. (cioè non 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"

La mia ipotesi è che questo soddisfi le tue esigenze. Naturalmente non è completamente protetto, ma dovrebbe essere sufficiente per iniziare. Consiglierei di leggerne un po 'di più su queste pagine. Ciò si rivelerà utile per 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 ottiene ancora molti punti di vista, ho pensato di aggiungere un esempio .replace usato con una funzione di callback. In questo caso, semplifica notevolmente l'espressione e fornisce ancora più flessibilità, come la sostituzione con la corretta maiuscola o la sostituzione di entrambi cat e cats in un colpo solo:

'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



Corrisponde a un'espressione regolare globale:

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

45
2018-05-06 23:23



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

Oppure prova la funzione replaceAll da qui:

Quali sono i metodi JavaScript utili che estendono gli oggetti incorporati?

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

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

MODIFICARE: Chiarimento su replaceAll availability

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'

34
2017-07-17 17:55



Supponi di voler sostituire tutti '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.


29
2017-09-10 14:59



Usa un'espressione regolare:

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

27
2017-07-17 17:56