Como substituir todas as ocorrências de uma string?

4383

Eu tenho esta string:

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

Fazendo:

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

parece remover apenas a primeira ocorrência de abcna sequência acima.

Como posso substituir todas as ocorrências dele?

Click Voto a favor
fonte
5
Ao substituir todas as ocorrências de abain ababapor ca, qual resultado você espera? caba? abca? cca?
Reinierpost
String.prototype.replaceAll()enviado no Safari 13.1 e agora no Firefox Nightly e Chrome Dev e Canary e será enviado no Firefox 77 e Chrome 85. Ainda não está documentado no MDN, mas github.com/tc39/proposal-string-replaceall#high-level-api tem um explicador: “Se searchValue for uma string, String.prototype.replaceAllsubstitui todas as ocorrências do searchValue (como se .split(searchValue).join(replaceValue)uma expressão regular global e com escape adequado tivesse sido usada). Se searchValue for uma expressão regular não global, String.prototype.replaceAlllançará uma exceção ”
sideshowbarker

Respostas:

1612

Nota: Não use isso no código crítico de desempenho.

Como alternativa às expressões regulares para uma cadeia literal simples, você pode usar

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

O padrão geral é

str.split(search).join(replacement)

Em alguns casos, isso costumava ser mais rápido do que usar replaceAll e uma expressão regular, mas isso não parece mais ser o caso nos navegadores modernos.

Referência: https://jsperf.com/replace-all-vs-split-join

Conclusão: Se você tiver um caso de uso crítico de desempenho (por exemplo, processando centenas de strings), use o método Regexp. Mas para os casos de uso mais comuns, vale a pena não ter que se preocupar com caracteres especiais.

Matthew Crumley
fonte
147
Isso me surpreendeu, pois eu esperava que esse método alocasse mais objetos, criasse mais lixo e, portanto, levasse mais tempo, mas quando eu realmente testei em um navegador, esse método era consistentemente cerca de 20% mais rápido que a resposta aceita. Os resultados podem variar, é claro.
MgSam
42
Fiquei curioso e configurei o seguinte: jsperf.com/replace-all-vs-split-join . Parece que a v8 é louca rapidamente ao dividir / juntar matrizes em comparação com outros mecanismos javascript.
Fabi
8
Muito bom - também evita a possibilidade de RegExps incorretos ao transmitir caracteres especiais. Estou adicionando um sinalizador genérico para "encontrar isso e substituí-lo" em uma propriedade de objeto, mas fiquei preocupado se eu precisasse substituir "." ou "}" e esqueceu que eu estava usando o RegEx 3 meses depois!
precisa
9
E como String.prototype: String.prototype.replaceAll = function(f,r){return this.split(f).join(r);}. Uso: "My string".replaceAll('st', '');produz "Meu anel"
MacroMan
8
Não vejo uma razão para o aviso não usar isso na produção. Não é mais um hack do que escapar de uma regex apenas porque você deseja substituir várias ocorrências, mas não precisa de uma regex em primeiro lugar. Apenas envolva esse "hack" em uma boa replaceAllfunção, e ele se torna tão legível quanto qualquer outra coisa. Como o desempenho não é ruim, não há razão para evitar esta solução.
youen
4385
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 do Click Upvote , você pode simplificá-lo ainda mais:

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

Nota: Expressões regulares contêm caracteres especiais (meta) e, como tal, é perigoso transmitir cegamente um argumento na findfunção acima sem pré-processá-lo para escapar desses caracteres. Isso é abordado no Guia de expressões regulares do Mozilla Developer Network , em JavaScript , onde eles apresentam a seguinte função de utilitário (que foi alterada pelo menos duas vezes desde que a resposta foi originalmente escrita, verifique o site MDN para possíveis atualizações):

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

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

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
Sean Bright
fonte
4
Expressões regulares são a única maneira de fazer isso "pronto para uso" sem implementar seu próprio método 'replaceAll'. Não estou sugerindo o uso deles apenas para usá-los.
217 Sean Bright
10
Esta é a minha própria função a partir deste comentário: function replaceAll(find, replace,str) { var re = new RegExp(find, 'g'); str = str.replace(re, replace); return str; }
Click Upvote
47
Uma ressalva importante da replaceAllimplementação é que ela não funcionará se findcontiver metacaracteres.
Martin Ender
1
@SeanBright você está certo. Eu usei seu javascript em um código php, então tive que adicionar uma barra invertida extra para escapar. No violino, seu código é perfeito. Eu deveria ter verificado. Pedido de
Onimusha
2
@Bennett, é uma prática inadequada estender o protótipo de tipos nativos JavaScript .
Emile Bergeron
2437

Por uma questão de integridade, comecei a pensar sobre qual método eu deveria usar para fazer isso. Existem basicamente duas maneiras de fazer isso, conforme sugerido pelas outras respostas nesta página.

Nota: Em geral, a extensão dos protótipos internos em JavaScript geralmente não é recomendada. Estou fornecendo como extensões no protótipo String apenas para fins de ilustração, mostrando diferentes implementações de um método padrão hipotético Stringno protótipo interno.


Implementação baseada em expressões regulares

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

Implementação de divisão e junção (funcional)

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

Sem saber muito sobre como as expressões regulares funcionam nos bastidores em termos de eficiência, eu costumava me inclinar para a divisão e ingressar na implementação no passado sem pensar em desempenho. Quando me perguntei o que era mais eficiente e com que margem, usei-o como desculpa para descobrir.

Na minha máquina Windows 8 Chrome, a implementação baseada em expressões regulares é a mais rápida , com a implementação de divisão e junção sendo 53% mais lenta . Significando que as expressões regulares são duas vezes mais rápidas para a entrada de lorem ipsum que eu usei.

Confira este benchmark executando essas duas implementações uma contra a outra.


Conforme observado no comentário abaixo de @ThomasLeduc e outros, pode haver um problema com a implementação baseada em expressões regulares se searchcontiver certos caracteres reservados como caracteres especiais em expressões regulares . A implementação pressupõe que o chamador escapará da string antecipadamente ou passará apenas as seqüências que estão sem os caracteres na tabela em Expressões regulares (MDN).

O MDN também fornece uma implementação para escapar de nossas strings. Seria bom se isso também fosse padronizado RegExp.escape(str), mas, infelizmente, não existe:

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

Poderíamos chamar escapeRegExpdentro de nossa String.prototype.replaceAllimplementação, no entanto, não tenho certeza de quanto isso afetará o desempenho (potencialmente mesmo para cadeias para as quais a fuga não é necessária, como todas as cadeias alfanuméricas).

Cory Gross
fonte
8
No Android 4.1, o método regexp é 15% mais rápido, mas você não está escapando da expressão a ser pesquisada, portanto, esse parâmetro de referência está incompleto.
andreszs
33
Há um problema com esta solução. Se sua string de pesquisa parecer conter caracteres especiais de uma expressão regexp, eles serão interpretados. Eu recomendo a resposta @Sandy Unitedwolf.
Thomas Leduc
2
O primeiro fará isso: 'bla.bla'.replaceAll ('. ',' _ '); "_______". O segundo fará 'bla_bla', que geralmente é o que você deseja fazer.
21416 RobKohr
1
@ThomasLeduc parece que a questão que você mencionou pode ser contornado com lodash => lodash.com/docs/4.17.5#escapeRegExp
Matthew Beck
1
Deixando esta aqui para os telespectadores futuras que também estão se perguntando por que estender o objeto nativo é uma má idéia: stackoverflow.com/questions/14034180/...
Ben Cooper
692

O uso de uma expressão regular com o gconjunto de sinalizadores substituirá todos:

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

Adam A
fonte
15
Meio bobo, eu acho, mas o regex global do JS é a única maneira de fazer várias substituições.
755 Mike
5
bem, tecnicamente, você pode fazer um loop através da var sourceTextcontagem do número de instâncias ( numOfInstances) usando substringou dividir e contar o comprimento (entre outras estratégias) de thatWhichYouWantToReplaceentão fazer for (var i = 0; i < numOfInstances; i++){ sourceText = sourceText.replace('thatWhichYouWantToReplace', '');} ou ainda mais fácil, basta usar um loop while ( while sourceText.indexOf(thatWhichYouWantToReplace > -1){ sourceText = sourceText.replace(...)), mas não vejo por que você desejaria faça dessa maneira quando o uso /gfor tão fácil e provavelmente com melhor desempenho.
Zargold
@Zargold Você gostaria de fazer um loop para garantir que, mesmo após a substituição, você substitua todas as instâncias, o que é uma pegadinha bastante comum. Veja minha resposta abaixo stackoverflow.com/a/26089052/87520
SamGoody
109

Aqui está uma função de protótipo de string com base na resposta aceita:

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

EDITAR

Se você findpossuir caracteres especiais, será necessário escapá-los:

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

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

jesal
fonte
5
Mas e se findcontiver caracteres como .ou $que tenham significados especiais no regex?
Callum #
1
@ callum Nesse caso, você teria que escapar da sua variável find (veja a edição acima).
jesal
jesal, esta é uma solução maravilhosa para um problema de substituição de string que encontrei e aparentemente supera a "imutabilidade" de strings em JavaScript. Você ou outra pessoa poderia explicar como essa função de protótipo substitui a imutabilidade de strings? Isso faz o trabalho; Eu só quero entender essa pergunta complementar que ela coloca.
Tom
1
@ Tom: Ele não supera a imutabilidade: var str = thiscria uma segunda referência à string imutável, à qual o replacemétodo é aplicado, que por sua vez retorna uma nova string imutável . essas funções de protótipo retornam uma nova sequência imutável; caso contrário, você seria capaz de escrever someStrVar.replaceAll('o', '0');e someStrVarseria alterado. Em vez disso, você deve escrever someStrVar = someStrVar.replaceAll('o', '0');<- reatribuir para definir o var para conter a nova sequência imutável . não há maneira de contornar isso. Tente no console:x = 'foobar'; x.replaceAll('o', '0'); x;
Elias Van Ootegem 15/06
87

Atualizar:

É um pouco tarde para uma atualização, mas desde que acabei de me deparar com essa pergunta e percebi que minha resposta anterior não é com a qual estou feliz. Como a pergunta envolvia substituir uma única palavra, é incrível que ninguém pensasse em usar limites de palavras ( \b)

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

Esse é um regex simples que evita substituir partes das palavras na maioria dos casos. No entanto, um traço -ainda é considerado um limite de palavra. Portanto, condicionais podem ser usados ​​neste caso para evitar a substituição de strings 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: Javascript substitui "'" por "' '"

@ Mike, verifique a resposta que eu dei lá ... regexp não é a única maneira de substituir várias ocorrências de uma assinatura, longe disso. Pense flexível, pense dividido!

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

Como alternativa, para evitar a substituição de partes de palavras, o que a resposta aprovada também fará! Você pode contornar esse problema usando expressões regulares que são, eu admito, um pouco mais complexas e, como resultado disso, um pouco mais devagar:

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

A saída é igual à resposta aceita, no entanto, usando a expressão / cat / g nesta cadeia de caracteres:

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

Opa, de fato, isso provavelmente não é o que você deseja. O que é então? IMHO, um regex que substitui apenas '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"

Meu palpite é que isso atenda às suas necessidades. Não é à prova de falhas, é claro, mas deve ser suficiente para você começar. Eu recomendo ler um pouco mais sobre estas páginas. Isso será útil para aperfeiçoar essa expressão para atender às suas necessidades específicas.

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

http://www.regular-expressions.info


Adição final:

Como essa pergunta ainda tem muitas visualizações, pensei em adicionar um exemplo de .replaceusado com uma função de retorno de chamada. Neste caso, ele simplifica dramaticamente a expressão e oferece ainda mais flexibilidade, como a substituição com capitalização correta ou substituição de ambos cate catsde 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
Elias Van Ootegem
fonte
Eu acho que a parte interessante adicional deve ser colocada na parte inferior. ps .: notei agora que a metade da primeira linha está fora da área, deixe-me consertar isso!
69

Combine com uma expressão regular global:

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

Para substituir uma única vez, use:

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

Para substituir várias vezes, use:

var res = str.replace(/abc/g, "");
Indrajeet Singh
fonte
para alguém precisar substituir \ n, você pode fazê-lo como:replace(/\n/g, '<br/>')
Phan Van Linh
58

Estes são os métodos mais comuns e legíveis.

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

Método 1:

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

Método 2:

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

Método 3:

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

Método 4:

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

Resultado:

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

Ou tente a função replaceAll a partir daqui:

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

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

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

EDITAR: Esclarecimento sobre a disponibilidade do replaceAll

O método 'replaceAll' é adicionado ao protótipo de String. Isso significa que estará disponível para todos os objetos / literais de string.

Por exemplo

var output = "test this".replaceAll('this', 'that');  //output is 'test that'.
output = output.replaceAll('that', 'this'); //output is 'test this'
SolutionYogi
fonte
2
Você pode reescrever a função replaceAll () para aqueles que não usam protótipo?
Click Upvote
@Clique para votar .... você está usando um protótipo, que faz parte de todos os objetos JS. Eu acho que você está pensando em prototype.js a biblioteca JS.
Seth
seth, uma pequena correção. Se você adicionar um método a um protótipo, ele estará disponível para todos os objetos desse tipo. O método replceAll foi adicionado ao protótipo String e deve funcionar para todos os objetos de string.
SolutionYogi
@solutionyogi - Sim, eu já usei protótipo (corretamente) antes. Eu estava apenas abordando o comentário do OP sobre "não usar prototype", que assumi como Prototype.js (talvez incorretamente?). Eu deveria ter dito "um protótipo" enquanto tentava dizer que objetos JavaScript têm um protótipo. Assim, o OP já estava 'usando protótipo', embora de forma "indireta". Indireto pode ser o termo errado para usar aqui, mas estou cansada demais.
Seth
41

O uso RegExpde JavaScript pode fazer o trabalho para você, basta fazer algo como o código abaixo, não se esqueça do /gseguinte destaque para global :

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 por você, mas isso não é recomendado, pois é apenas uma função de linha, mas novamente, se você usar isso intensamente, poderá escrever algo como isto:

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

e simplesmente use-o no seu código repetidamente, como abaixo:

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

Mas, como mencionei anteriormente, não fará uma grande diferença em termos de linhas a serem gravadas ou desempenho, apenas o cache da função poderá afetar um desempenho mais rápido em seqüências longas e também uma boa prática de código DRY se você desejar reutilizar.

Alireza
fonte
40

Digamos que você queira 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

Eu estava tentando pensar em algo mais simples do que modificar o protótipo de string.

Emilio Grisolía
fonte
1
Simples, fácil e provavelmente a opção com melhor desempenho: boa resposta.
machineghost
Na verdade, embora eu não tenha medido pessoalmente, a divisão / junção geralmente é uma solução de alto desempenho.
machineghost
1
é ainda em cromo, 100% mais rápido no Firefox, e 50% mais lento no IE ...: jsperf.com/replace-regex-split-join
Olivier
37

Use uma expressão regular:

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

Substituindo aspas simples:

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

    return text;
}
Chris Rosete
fonte
2
Como posso mudar a segunda linha para substituir as strings? Isso não funciona: text = text.replace ('ei', 'olá'); Qualquer ideia?
Stefan Đorđević
2
Claro Stefan, aqui está o código ... text = text.replace (/ hey / g, 'olá');
Chris Rosete
26

// faz um loop até que o número de ocorrências chegue a 0. OU simplesmente copie / cole

    function replaceAll(find, replace, str) 
    {
      while( str.indexOf(find) > -1)
      {
        str = str.replace(find, replace);
      }
      return str;
    }
Raseela
fonte
23
Este método é perigoso, não o use. Se a sequência de substituição contiver a palavra-chave de pesquisa, ocorrerá um loop infinito. No mínimo, armazene o resultado de .indexOfem uma variável e use-a como o segundo parâmetro de .indexOf(menos o comprimento da palavra-chave, mais o comprimento da cadeia de substituição).
Rob W
Estou pensando em primeiro substituir o padrão de pesquisa por um caractere unicode weired, de que temos certeza de que ele não é usado na string de entrada. Como U + E000 na área privada. E depois substitua-o de volta ao alvo. Eu construí isso aqui. . Não sei se é uma boa ideia.
Lux
26
str = str.replace(new RegExp("abc", 'g'), "");

funcionou melhor para mim do que as respostas acima. por isso new RegExp("abc", 'g')cria um RegExp o que corresponde a todos ocorrência ( 'g'flag) do texto ( "abc"). A segunda parte é a que é substituída, no seu caso, string vazia ( ""). stré a string, e precisamos substituí-la, pois replace(...)apenas retorna resultado, mas não substitui. Em alguns casos, você pode querer usar isso.

csomakk
fonte
Embora esse snippet de código possa ser a solução, incluir uma explicação realmente ajuda a melhorar a qualidade da sua postagem. Lembre-se de que você está respondendo à pergunta dos leitores no futuro e essas pessoas podem não saber os motivos da sua sugestão de código.
yivi
Sim você está certo. adicionado. Também editei para responder à pergunta original :)
csomakk
Nota: g bandeira no meio regex é sinalizador global que irá corresponder a todas as ocorrências
firstpostcommenter
25

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

Jsperf revisado

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 mais rápido que o método de divisão e junção.

Conforme indicado em um comentário aqui, isso não funcionará se a sua omitvariável contiver place, como em:, replaceAll("string", "s", "ss")porque sempre poderá substituir outra ocorrência da palavra.

Há outro jsperf com variantes na minha substituição recursiva que é ainda mais rápida ( http://jsperf.com/replace-all-vs-split-join/12 )!

  • Atualização 27 de julho de 2017: Parece que o RegExp agora tem o desempenho mais rápido no Chrome 59, lançado recentemente.
Cole Lawrence
fonte
Adorei sua solução ... Gostaria de poder lhe dar +10, mas aqui está o meu +1. Eu acho que você pode armazenar o índice da sub-string que foi substituída e pular para a próxima se uma correspondência for encontrada em um índice mais baixo para evitar esse problema de loop infinito. Não posso comentar sobre o desempenho porque não testei, mas esses são apenas meus 2 centavos neste pedaço de excelência.
Fr0zenFyr
@ fr0zenfyr se você quiser verificar se omitir está no lugar (para evitar loop infinito) você poderia fazer uma condicional como if(place.replace(omit) === omit) {No jogo, por isso é seguro para uso substituir circuito } else {Jogo então use método diferente, como dividir e juntar}
Cole Lawrence
Hmm .. mas qual é o sentido de combinar duas soluções? Eu não sou assim mesmo um fã de Split / associar-se abordagem de qualquer maneira .. obrigado pela aconselhar ..
Fr0zenFyr
@ Fr0zenFyr Eu acredito que o objetivo de combinar as duas soluções seria o fallback de um método mais lento se você não puder usar o mais rápido (quando o loop seria infinito, por exemplo). Portanto, seria uma proteção segura garantir a funcionalidade com eficiência, mas sem possibilidade de falha.
Cole Lawrence
@momomo como falho?
SandRock 8/08/19
24

atuação

Hoje em 27.12.2019, realizo testes no macOS v10.13.6 (High Sierra) para as soluções escolhidas.

Conclusões

  • O str.replace(/abc/g, '');( C ) é uma boa solução rápida entre navegadores para todas as strings.
  • As soluções baseadas em split-join( A, B ) ou replace( C, D ) são rápidas
  • As soluções baseadas em while( E, F, G, H ) são lentas - geralmente ~ 4 vezes mais lentas para cordas pequenas e cerca de 3000 vezes (!) Mais lentas para cordas longas
  • As soluções de recorrência ( RA, RB ) são lentas e não funcionam para seqüências longas

Eu também crio minha própria solução. Parece que atualmente é o mais curto que faz o trabalho de pergunta:

str.split`abc`.join``

Detalhes

Os testes foram realizados no Chrome 79.0, Safari 13.0.4 e Firefox 71.0 (64 bits). Os testes RAe RBusam recursão. Resultados

Digite a descrição da imagem aqui

String curta - 55 caracteres

Você pode executar testes em sua máquina AQUI . Resultados para o Chrome:

Digite a descrição da imagem aqui

Sequência longa: 275 000 caracteres

As soluções recursivas RA e RB oferecem

RangeError: tamanho máximo da pilha de chamadas excedido

Para 1 milhão de caracteres, eles até quebram o Chrome

insira a descrição da imagem aqui

Eu tento executar testes de caracteres de 1 milhão para outras soluções, mas E, F, G, H leva tanto tempo que o navegador me pede para quebrar o script, então reduzo a sequência de teste para 275 mil caracteres. Você pode executar testes em sua máquina AQUI . Resultados para Chrome

insira a descrição da imagem aqui

Código usado nos testes

Kamil Kiełczewski
fonte
1
Agora, essa é uma resposta profunda e profunda! Muito obrigado! No entanto, o que me interessa é por que a sintaxe do "novo RegExp (...)" oferece uma grande melhoria.
Márk Gergely Dolinka
21

Se o que você deseja encontrar já estiver em uma sequência e não tiver um escaper de regex à mão, poderá usar 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'));

rakslice
fonte
obrigado! Esta solução funciona perfeitamente para o meu 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;
}
Tim Rivoli
fonte
Gostaria de saber o quão bem isso executa ... substring é nativo ou percorre o array de caracteres para criar os novos caracteres.
mmm
16

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

text = text.replace(new RegExp("cat","g"), "dog"); 
Owen
fonte
1
Ok, como você escapa a string para usá-la como um padrão regex?
rakslice
Eu não, eu só usá-lo para texto simples
Owen
15

A maneira mais simples de fazer isso sem usar qualquer regex é dividir e associar-se como o código aqui:

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

http://jsfiddle.net/ANHR9/

pkdkk
fonte
qual foi o ponto de um violino que só contém o mesmo javascript
JGallardo
13
while (str.indexOf('abc') !== -1)
{
    str = str.replace('abc', '');
}
zdennis
fonte
13

Se a string contiver um padrão semelhante abccc, você pode usar isto:

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

As respostas anteriores são muito complicadas. Basta usar a função de substituição como esta:

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

Exemplo:

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

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

console.log(res);

Preto
fonte
10

Se você estiver tentando garantir que a string que você está procurando não exista mesmo após a substituição, será necessário usar um loop.

Por exemplo:

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

Quando concluído, você ainda terá 'test abc'!

O loop mais simples para resolver isso seria:

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

Mas isso executa a substituição duas vezes para cada ciclo. Talvez (sob risco de ser rejeitado) possa ser combinado de 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 '!

Isso pode ser particularmente útil ao procurar seqüências de caracteres duplicadas.
Por exemplo, se tivermos 'a ,,, b' e desejarmos remover todas as vírgulas duplicadas.
[Nesse caso, é possível substituir. (/, + / G, ','), mas em algum momento o regex fica complexo e lento o suficiente para fazer um loop.]

SamGoody
fonte
10

Embora as pessoas tenham mencionado o uso de regex, existe uma abordagem melhor se você deseja substituir o texto, independentemente do caso. Como maiúsculas ou minúsculas. Use a sintaxe abaixo

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

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

Você pode consultar o exemplo detalhado aqui .

Código Cheezy
fonte
a partir do exemplo site: "/ toBeReplacedString / gi é o regex que você precisa para usar aqui g representa para o jogo global e i representa maiúsculas e minúsculas por regex padrão é sensível a maiúsculas.."
alikuli
8

Você pode simplesmente usar 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);
};
tk_
fonte
7

Basta adicionar /g

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

para

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

/g significa global

Reza Fahmi
fonte