Como substituir todas as ocorrências de uma string em JavaScript?

tenho este texto:

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

a fazer

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

parece apenas remover a primeira ocorrência de abc na sequência acima. Como posso substituir todas as ocorrências dele?

Author: Lamy, 2009-07-17

30 answers

Por uma questão de exaustividade, comecei a pensar em que método devo usar para fazer isto. Existem basicamente duas maneiras de fazer isso como sugerido pelas outras respostas nesta página.

Nota: Em geral, não se recomenda a extensão dos protótipos incorporados no JavaScript. Eu estou fornecendo como extensões no protótipo String simplesmente para fins de ilustração, mostrando diferentes implementações de um hipotético método padrão no String embutido prototipo.


Implementação Baseada Em Expressões Regulares

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

Dividir e juntar (funcional) implementação

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

Não sabendo muito sobre como as expressões regulares funcionam nos bastidores em termos de eficiência, tendi a inclinar-me para a separação e juntar-me à implementação no passado sem pensar no desempenho. Quando me perguntei o que seria mais eficiente, e por que margem, usei-o como desculpa para descobrir.

Nas minhas janelas cromadas 8 machine, a implementação baseada em expressões regulares é a mais rápida , com a divisão e implementação de juntas sendo 53% mais lenta . O que significa que as expressões regulares são duas vezes mais rápidas para a entrada ipsum lorem que eu usei.

Olha para isto. parâmetro de referência executando estas duas implementações umas contra as outras.
Como indicado no comentário abaixo por @ThomasLeduc e outros, pode haver um problema com a implementação regular baseada em expressões se search contiver certos caracteres reservados como caracteres especiais em expressões regulares . A implementação assume que o chamador vai escapar da string de antemão ou só vai passar strings que estão sem os caracteres na tabela em Expressões Regulares (MDN). O MDN também fornece uma implementação para escapar às nossas cordas. Seria bom se isto também fosse padronizado como RegExp.escape(str), mas infelizmente, não existe:
function escapeRegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}

Nós could call escapeRegExp within our String.prototype.replaceAll implementation, however, i'm not sure how much this will affect the performance (potentially even for strings for which the escape is not needed, like all alfanumeric strings).

 1752
Author: Cory Gross, 2017-05-27 21:55:56
str = str.replace(/abc/g, '');

Em resposta ao comentário:

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

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

Em resposta ao Comentário de Click Upvote, Você poderia simplificá-lo ainda mais:

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

Nota: as expressões regulares contêm caracteres especiais (meta) e, como tal, é perigoso passar cegamente um argumento na função find acima sem pré-processá-lo para escapar a esses caracteres. Isto está coberto no Guia de JavaScript Mozilla Developer Network'S no Guia de Expressões Regulares , onde apresentam a seguinte função de utilidade:

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

De modo a tornar a função replaceAll() acima mais segura, pode ser modificada para o seguinte se também incluir:escapeRegExp:

function replaceAll(str, find, replace) {
    return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
 3686
Author: Sean Bright, 2017-06-21 22:17:14

Nota: não use isto em código real.

Como uma alternativa às expressões regulares para um texto literal simples, você poderia usar

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

O padrão geral é

str.split(search).join(replacement)

Isto costumava ser mais rápido em alguns casos do que usar {[[2]} e uma expressão regular, mas isso já não parece ser o caso nos navegadores modernos. Então, isso realmente só deve ser usado como um hack rápido para evitar a necessidade de escapar da expressão regular, não em código real.

 1207
Author: Matthew Crumley, 2017-01-24 14:38:59

Se usar uma expressão regular com a opção g irá substituir todas:

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

Veja aqui também

 519
Author: Adam A, 2016-05-17 12:15:25

Aqui está uma função protótipo de cadeia de caracteres com base na resposta aceite:

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

Editar

Se o seu find contiver caracteres especiais, então terá de fugir deles:

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

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

 92
Author: jesal, 2013-10-07 16:40:16

actualizar:

É um pouco tarde para uma actualização, mas já que tropecei nesta pergunta, e reparei que a minha resposta anterior não me agrada. Uma vez que a pergunta envolvia substituir uma única palavra, é incrível que ninguém tenha pensado em usar limites de palavras.(\b)
'a cat is not a caterpillar'.replace(/\bcat\b/gi,'dog');
//"a dog is not a caterpillar"
Este é um simples vértice que evita a substituição de Partes de palavras na maioria dos casos. No entanto, um traço - ainda é considerado um limite de palavra. Assim os condicionalismos podem ser usado neste caso para evitar substituir textos como 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"

Basicamente, esta pergunta é a mesma que a pergunta aqui.: o Javascript substitui "'" por "" " @Mike, verifica a resposta que dei... regexp não é a única maneira de substituir múltiplas ocorrências de uma subseção, longe disso. Pensa flexível, pensa dividido!
var newText = "the cat looks like a cat".split('cat').join('dog');

Em alternativa, para evitar a substituição de partes do termo-o que a resposta aprovada também fará! Você pode contornar esta questão usando expressões regulares que são, admito, um pouco mais complexas e como resultado disso, um pouco mais lentas também:

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

O resultado é o mesmo que a resposta aceite, no entanto, usando a expressão de /cat/g nesta cadeia:

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" ?? 
De facto, isto provavelmente não é o que tu queres. O que é, então? IMHO, um regex que só substitui o "gato" condicionalmente. (ou seja, não faz parte de uma palavra), assim:
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"
O meu palpite é que isto vai ao encontro das tuas necessidades. Não é totalmente à prova, claro, mas é deve ser o suficiente para começar. Recomendo ler mais nestas páginas. Isto será útil para aperfeiçoar esta expressão para satisfazer as suas necessidades específicas.

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

Http://www.regular-expressions.info


Adição Final:

Dado que esta questão ainda tem muitas vistas, pensei em Adicionar um exemplo de .replace usado com uma função de callback. Neste case, simplifica dramaticamente a expressão e proporciona ainda mais flexibilidade, como substituir por capitalização correta ou substituir ambos cat e cats de uma só vez:

'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
Author: Elias Van Ootegem, 2017-05-23 11:47:36

Jogo contra uma expressão regular global:

anotherString = someString.replace(/cat/g, 'dog');
 51
Author: scronide, 2009-05-06 23:23:40
str = str.replace(/abc/g, '');

Ou tente a função de substituição a partir daqui:

Quais são os métodos de JavaScript úteis que estendem objetos incorporados?

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

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

Editar: clarificação sobre a disponibilidade de substituição

O método' replaceAll ' é adicionado ao protótipo do String. Isto significa que estará disponível para todos os objectos de texto/literais.

Por exemplo

var output = "test this".replaceAll('this', 'that');  //output is 'test that'.
output = output.replaceAll('that', 'this'); //output is 'test this'
 35
Author: SolutionYogi, 2017-05-23 12:34:57

Diga que quer substituir todo o ' abc ' por '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
Estava a tentar pensar em algo mais simples do que modificar o protótipo das cordas.
 30
Author: Emilio Grisolía, 2017-05-27 22:01:59

Utilizar uma expressão regular:

str.replace(/abc/g, '');
 27
Author: Donnie DeBoer, 2017-05-27 21:56:32

Substituindo aspas simples:

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

    return text;
}
 25
Author: Chris OnDaRocks, 2017-12-17 15:53:28

/ / loop it until number occurrence comes to 0. Ou simplesmente copiar / colar

    function replaceAll(find, replace, str) 
    {
      while( str.indexOf(find) > -1)
      {
        str = str.replace(find, replace);
      }
      return str;
    }
 22
Author: Raseela, 2013-09-05 14:01:12

Esta é a versão mais rápida que não usa expressões regulares .

Jsperf revisto

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

É quase duas vezes tão rápido quanto o método de separação e junção.

Como apontado em um comentário aqui, isso não vai funcionar se o seu omit variável contém place, como em: replaceAll("string", "s", "ss"), porque ele sempre será capaz de substituir outra ocorrência da palavra.

Há outro jsperf com variantes no meu substituto recursivo que vão ainda mais rápido ( http://jsperf.com/replace-all-vs-split-join/12)!
  • Update July 27th 2017: It looks like RegExp now has the fastest performance in the recently released Chrome 59.
 20
Author: Cole Lawrence, 2017-07-27 15:57:56
str = str.replace(new RegExp("abc", 'g'), "");
Funcionou melhor para mim do que as respostas acima. então new RegExp("abc", 'g') cria uma expressão regular que corresponde a toda a ocorrência ('g') do texto ("abc"). A segunda parte é o que é substituído, no seu caso Texto vazio (""). str é o texto, e temos de o anular, pois replace(...) apenas devolve o resultado, mas não substitui. Em alguns casos você pode querer usar isso.
 19
Author: csomakk, 2017-12-29 17:52:40
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;
}
 15
Author: Tim Rivoli, 2014-09-29 19:17:45

Se o que quer encontrar já estiver numa corda, e não tiver um escapador regex à mão, pode usar o 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'));
 14
Author: rakslice, 2018-07-23 17:42:33
var str = "ff ff f f a de def";
str = str.replace(/f/g,'');
alert(str);

Http://jsfiddle.net/ANHR9/

 12
Author: pkdkk, 2013-09-04 10:01:17
while (str.indexOf('abc') !== -1)
{
    str = str.replace('abc', '');
}
 12
Author: zdennis, 2014-04-29 10:25:12

Usar RegExp em o JavaScript pode fazer o trabalho por ti, basta fazer algo como abaixo:

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

Se você pensar em reutilizar, crie uma função para fazer isso para você, mas não é recomendado, pois é apenas uma função de linha, mas novamente se você tiver muito uso disso, você pode escrever algo assim:

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

E basta usá - lo no seu código vezes sem conta do seguinte modo:

var str ="Test abc test test abc test test test abc test test abc";
str = str.replaceAll('abc', '');
Mas, como já mencionei, não fará grande diferença em termos de linhas a serem escrito ou desempenho, apenas cache a função pode afetar um desempenho mais rápido em cadeias longas e também uma boa prática de código seco, se você quiser reutilizar.
 11
Author: Alireza, 2018-07-12 05:57:29

Gosto deste método (parece um pouco mais limpo):

text = text.replace(new RegExp("cat","g"), "dog"); 
 10
Author: Owen, 2017-05-27 21:57:29

Se o texto contém um padrão semelhante ao abccc, pode usar isto:

str.replace(/abc(\s|$)/g, "")
 10
Author: mostafa elmadany, 2018-04-27 08:49:49

Se está a tentar garantir que a cadeia de caracteres que procura não existirá mesmo após a substituição, precisa de usar um laço.

Por exemplo:

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

Quando completo, você ainda terá 'teste abc'!

O loop mais simples para resolver isto seria:

var str = 'test aabcbc';
while (str != str.replace(/abc/g, '')){
   str.replace(/abc/g, '');
}
Mas isso faz a substituição duas vezes por cada ciclo. Talvez (correndo o risco de ser rejeitado) isso possa ser combinado para uma forma um pouco mais eficiente, mas menos legível:
var str = 'test aabcbc';
while (str != (str = str.replace(/abc/g, ''))){}
// alert(str); alerts 'test '!

Isto pode ser particularmente útil ao procurar por sequências duplicadas.
Por exemplo, se tivermos 'a,,, b' e quisermos remover todas as vírgulas duplicadas.
Nesse caso, pode ser.substitua (/,+ / g,','), Mas em algum momento o regex fica complexo e lento o suficiente para fazer o loop.]

 9
Author: SamGoody, 2014-09-28 19:58:42
var string  = 'Test abc Test abc Test abc Test abc'
string = string.replace(/abc/g, '')
console.log(string)
 9
Author: Ashutosh Narang, 2018-03-09 09:41:05
Podes tentar combinar estes dois métodos poderosos.
"test abc test test abc".split("abc").join("")
Espero que ajude!
 7
Author: Victor, 2013-10-09 15:04:23

Pode simplesmente utilizar o método abaixo

/**
 * 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
Author: tk_, 2016-02-23 03:47:11

Embora as pessoas tenham mencionado o uso da regex, mas há uma abordagem melhor se você quiser substituir o texto, independentemente do caso do texto. Como maiúsculas ou minúsculas. Usar abaixo da sintaxe

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

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

Pode consultar o exemplo detalhado aqui .

 7
Author: Cheezy Code, 2016-06-08 18:51:40

Basta seguir este oneliner regex adicionando a sensibilidade ao caso, então se você fizer "ABC", ele agiria da mesma forma que para"abc".

str = str.replace(/abc/gi, "");
 7
Author: Ankit, 2018-09-17 12:58:22

Basta adicionar /g

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

A

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

/g significa global

 6
Author: Reza Fahmi, 2015-10-15 12:13:18

A seguinte função funciona para mim:

String.prototype.replaceAllOccurence = function(str1, str2, ignore) 
{
    return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/\$/g,"$$$$"):str2);
} ;

Agora chama as funções assim:

"you could be a Project Manager someday, if you work like this.".replaceAllOccurence ("you", "I");

Basta copiar e colar este código na consola do seu navegador para testar.

 6
Author: Sandeep Gantait, 2016-02-16 09:53:06

Uso p para guardar o resultado da substituição da recursão anterior:

function replaceAll(s, m, r, p) {
    return s === p || r.contains(m) ? s : replaceAll(s.replace(m, r), m, r, s);
}

Irá substituir todas as ocorrências na sequência s até ser possível:

replaceAll('abbbbb', 'ab', 'a') → 'abbbb' → 'abbb' → 'abb' → 'ab' → 'a'

Para evitar o ciclo infinito, verifico se a substituição R contém uma correspondência m:

replaceAll('abbbbb', 'a', 'ab') → 'abbbbb'
 5
Author: Termininja, 2017-02-25 05:45:24