Método mais rápido para replace todas as instâncias de um caractere em uma string

Qual é a maneira mais rápida de replace todas as instâncias de uma string/character em uma string em Javascript ? Um while , um for-loop , uma regular expression ?

O mais fácil seria usar uma expressão regular com sinalizador g para replace todas as instâncias:

 str.replace(/foo/g, "bar") 

Isto irá replace todas as ocorrências de foo com bar na string str . Se você apenas tiver uma string, poderá convertê-la em um object RegExp como este:

 var pattern = "foobar", re = new RegExp(pattern, "g"); 

Experimente este replaceAll: http://dumpsite.com/forum/index.php?topic=4.msg8#msg8

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

É muito rápido, e funcionará para TODAS estas condições que muitos outros falham:

 "x".replaceAll("x", "xyz"); // xyz "x".replaceAll("", "xyz"); // xyzxxyz "aA".replaceAll("a", "b", true); // bb "Hello???".replaceAll("?", "!"); // Hello!!! 

Deixe-me saber se você pode quebrá-lo, ou você tem algo melhor, mas certifique-se que pode passar esses 4 testes.

 var mystring = 'This is a string'; var newString = mystring.replace(/i/g, "a"); 

newString agora é ‘Thas como um estranho’

Além disso, você pode tentar:

 string.split('foo').join('bar'); 

Você pode usar o seguinte:

 newStr = str.replace(/[^a-z0-9]/gi, '_'); 

ou

 newStr = str.replace(/[^a-zA-Z0-9]/g, '_'); 

Isso replaceá todos os caracteres que não sejam letras ou números por (‘_’). Simples altere o valor de sublinhado para o que você deseja substituí-lo.

Pensando nisso a partir de uma questão de velocidade, acredito que o exemplo de caso específico fornecido no link acima seria, de longe, a solução mais rápida.

 var token = "\r\n"; var newToken = " "; var oldStr = "This is a test\r\nof the emergency broadcasting\r\nsystem."; newStr = oldStr.split(token).join(newToken); 

newStr seria “Este é um teste do sistema de transmissão de emergência.”

Eu acho que a verdadeira resposta é que isso depende completamente de como suas inputs se parecem. Eu criei um JsFiddle para testar vários desses e alguns contra inputs. Não importa como eu olhe para os resultados, não vejo nenhum vencedor claro.

  • O RegExp não foi o mais rápido em nenhum dos casos de teste, mas também não foi ruim.
  • A abordagem Split / Join parece mais rápida para substituições esparsas.
  • Este que eu escrevi parece mais rápido para pequenos insumos e substituições densas:

     function replaceAllOneCharAtATime(inSource, inToReplace, inReplaceWith) { var output=""; var firstReplaceCompareCharacter = inToReplace.charAt(0); var sourceLength = inSource.length; var replaceLengthMinusOne = inToReplace.length - 1; for(var i = 0; i < sourceLength; i++){ var currentCharacter = inSource.charAt(i); var compareIndex = i; var replaceIndex = 0; var sourceCompareCharacter = currentCharacter; var replaceCompareCharacter = firstReplaceCompareCharacter; while(true){ if(sourceCompareCharacter != replaceCompareCharacter){ output += currentCharacter; break; } if(replaceIndex >= replaceLengthMinusOne) { i+=replaceLengthMinusOne; output += inReplaceWith; //was a match break; } compareIndex++; replaceIndex++; if(i >= sourceLength){ // not a match break; } sourceCompareCharacter = inSource.charAt(compareIndex) replaceCompareCharacter = inToReplace.charAt(replaceIndex); } replaceCompareCharacter += currentCharacter; } return output; } 

Qual é o mais rápido eu não sei, mas eu sei o que é mais legível – o que é mais curto e simples. Mesmo que seja um pouco mais lento que outra solução, vale a pena usar.

Então use:

  "string".replace("a", "b"); "string".replace(/abc?/g, "def"); 

E aproveite um bom código em vez de mais rápido (bem … 1/100000 seg. Não é uma diferença) e um feio. 😉

Use o object Regex como este

var regex = new RegExp('"', 'g'); str = str.replace(regex, '\'');

Ele replaceá toda a ocorrência de " em ' .

Use o método replace() do object String .

Como mencionado na resposta selecionada, o sinalizador / g deve ser usado na regex, para replace todas as ocorrências da subseqüência na seqüência de caracteres.

Eu tentei várias dessas sugestões depois de perceber que uma implementação que eu havia escrito sobre isso provavelmente há 10 anos não funcionou completamente (bug de produção desagradável em um sistema há muito esquecido, não é sempre assim?) … o que eu notei é que os que eu tentei (eu não tentei todos eles) tiveram o mesmo problema que o meu, ou seja, eles não replaceiam TODAS as ocorrências, apenas a primeira, pelo menos para o meu caso de teste obtendo “test …. txt” até “test.txt” substituindo “..” por “.” … talvez eu tenha perdido a situação de regex? Mas eu divago …

Então, eu reescrevi minha implementação da seguinte maneira. É bem simples, embora eu desconfie que não seja o mais rápido, mas também não acho que a diferença importará com os motores JS modernos, a menos que você esteja fazendo isso dentro de um circuito fechado, é claro, mas esse é sempre o caso de qualquer coisa …

 function replaceSubstring(inSource, inToReplace, inReplaceWith) { var outString = inSource; while (true) { var idx = outString.indexOf(inToReplace); if (idx == -1) { break; } outString = outString.substring(0, idx) + inReplaceWith + outString.substring(idx + inToReplace.length); } return outString; } 

Espero que ajude alguém!

 // Find, Replace, Case // ie "Test to see if this works? (Yes|No)".replaceAll('(Yes|No)', 'Yes!'); // ie2 "Test to see if this works? (Yes|No)".replaceAll('(yes|no)', 'Yes!', true); String.prototype.replaceAll = function(_f, _r, _c){ var o = this.toString(); var r = ''; var s = o; var b = 0; var e = -1; if(_c){ _f = _f.toLowerCase(); s = o.toLowerCase(); } while((e=s.indexOf(_f)) > -1) { r += o.substring(b, b+e) + _r; s = s.substring(e+_f.length, s.length); b += e+_f.length; } // Add Leftover if(s.length>0){ r+=o.substring(o.length-s.length, o.length); } // Return New String return r; };