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 abc
na sequência acima.
Como posso substituir todas as ocorrências dele?
javascript
string
replace
Click Voto a favor
fonte
fonte
aba
inababa
porca
, qual resultado você espera?caba
?abca
?cca
?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.replaceAll
substitui 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.replaceAll
lançará uma exceção ”Respostas:
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
O padrão geral é
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.
fonte
String.prototype.replaceAll = function(f,r){return this.split(f).join(r);}
. Uso:"My string".replaceAll('st', '');
produz "Meu anel"replaceAll
funçã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.Em resposta ao comentário:
Em resposta ao comentário do Click Upvote , você pode simplificá-lo ainda mais:
Nota: Expressões regulares contêm caracteres especiais (meta) e, como tal, é perigoso transmitir cegamente um argumento na
find
funçã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):Portanto, para tornar a
replaceAll()
função acima mais segura, ela pode ser modificada para o seguinte se você também incluirescapeRegExp
:fonte
function replaceAll(find, replace,str) { var re = new RegExp(find, 'g'); str = str.replace(re, replace); return str; }
replaceAll
implementação é que ela não funcionará sefind
contiver metacaracteres.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
String
no protótipo interno.Implementação baseada em expressões regulares
Implementação de divisão e junção (funcional)
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
search
contiver 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:Poderíamos chamar
escapeRegExp
dentro de nossaString.prototype.replaceAll
implementaçã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).fonte
O uso de uma expressão regular com o
g
conjunto de sinalizadores substituirá todos:Veja aqui também
fonte
var sourceText
contagem do número de instâncias (numOfInstances
) usandosubstring
ou dividir e contar o comprimento (entre outras estratégias) dethatWhichYouWantToReplace
então fazerfor (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/g
for tão fácil e provavelmente com melhor desempenho.Aqui está uma função de protótipo de string com base na resposta aceita:
EDITAR
Se você
find
possuir caracteres especiais, será necessário escapá-los:Fiddle: http://jsfiddle.net/cdbzL/
fonte
find
contiver caracteres como.
ou$
que tenham significados especiais no regex?var str = this
cria uma segunda referência à string imutável, à qual oreplace
mé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 escreversomeStrVar.replaceAll('o', '0');
esomeStrVar
seria alterado. Em vez disso, você deve escreversomeStrVar = 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;
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
)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 comocool-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!
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:
A saída é igual à resposta aceita, no entanto, usando a expressão / cat / g nesta cadeia de caracteres:
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:
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
.replace
usado 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 amboscat
ecats
de uma só vez:fonte
Combine com uma expressão regular global:
fonte
Para substituir uma única vez, use:
Para substituir várias vezes, use:
fonte
replace(/\n/g, '<br/>')
Estes são os métodos mais comuns e legíveis.
Método 1:
Método 2:
Método 3:
Método 4:
Resultado:
fonte
Ou tente a função replaceAll a partir daqui:
Quais são os métodos JavaScript úteis que estendem objetos internos?
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
fonte
O uso
RegExp
de JavaScript pode fazer o trabalho para você, basta fazer algo como o código abaixo, não se esqueça do/g
seguinte destaque para global :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:
e simplesmente use-o no seu código repetidamente, como abaixo:
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.
fonte
Digamos que você queira substituir todo o 'abc' por 'x':
Eu estava tentando pensar em algo mais simples do que modificar o protótipo de string.
fonte
Use uma expressão regular:
fonte
Substituindo aspas simples:
fonte
// faz um loop até que o número de ocorrências chegue a 0. OU simplesmente copie / cole
fonte
.indexOf
em 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).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, poisreplace(...)
apenas retorna resultado, mas não substitui. Em alguns casos, você pode querer usar isso.fonte
Esta é a versão mais rápida que não usa expressões regulares .
Jsperf revisado
É 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
omit
variável contiverplace
, 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 )!
fonte
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}
atuação
Hoje em 27.12.2019, realizo testes no macOS v10.13.6 (High Sierra) para as soluções escolhidas.
Conclusões
str.replace(/abc/g, '');
( C ) é uma boa solução rápida entre navegadores para todas as strings.split-join
( A, B ) oureplace
( C, D ) são rápidaswhile
( E, F, G, H ) são lentas - geralmente ~ 4 vezes mais lentas para cordas pequenas e cerca de 3000 vezes (!) Mais lentas para cordas longasEu também crio minha própria solução. Parece que atualmente é o mais curto que faz o trabalho de pergunta:
Mostrar snippet de código
Detalhes
Os testes foram realizados no Chrome 79.0, Safari 13.0.4 e Firefox 71.0 (64 bits). Os testes
RA
eRB
usam recursão. ResultadosString curta - 55 caracteres
Você pode executar testes em sua máquina AQUI . Resultados para o Chrome:
Sequência longa: 275 000 caracteres
As soluções recursivas RA e RB oferecem
Para 1 milhão de caracteres, eles até quebram o Chrome
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
Código usado nos testes
Mostrar snippet de código
fonte
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:
fonte
fonte
Eu gosto deste método (parece um pouco mais limpo):
fonte
A maneira mais simples de fazer isso sem usar qualquer regex é dividir e associar-se como o código aqui:
fonte
http://jsfiddle.net/ANHR9/
fonte
fonte
Se a string contiver um padrão semelhante
abccc
, você pode usar isto:fonte
As respostas anteriores são muito complicadas. Basta usar a função de substituição como esta:
Exemplo:
fonte
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:
Quando concluído, você ainda terá 'test abc'!
O loop mais simples para resolver isso seria:
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:
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.]
fonte
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
Você pode consultar o exemplo detalhado aqui .
fonte
Você pode simplesmente usar o método abaixo
fonte
Basta adicionar
/g
para
/g
significa globalfonte