I always used to copy a method to simulate a replaceAll with the javascript’s prototype, never thinking about speed. Now I decided to go and create a method by myself that do this and also allows you to ignore the case. The only bad thing (or not) is that you can’t use regex, just regular strings =(.
The example below uses all the possible stuff I could to create a faster and compact replaceAll method:
/**
* ReplaceAll by Fagner Brack (MIT Licensed)
* Replaces all occurrences of a substring in a string
*/
String.prototype.replaceAll = function( token, newToken, ignoreCase ) {
var _token;
var str = this + "";
var i = -1;
if ( typeof token === "string" ) {
if ( ignoreCase ) {
_token = token.toLowerCase();
while( (
i = str.toLowerCase().indexOf(
token, i >= 0 ? i + newToken.length : 0
) ) !== -1
) {
str = str.substring( 0, i ) +
newToken +
str.substring( i + token.length );
}
} else {
return this.split( token ).join( newToken );
}
}
return str;
};
How to use:
var str = "My house is clean... so clean... Clean";
var _str = "There are 15 sheeps in the 2 ships transporting 14 chips";
var str1 = str.replaceAll("clean", "dirty"); //"My house is dirty... so dirty... Clean"
var str2 = str.replaceAll("clean", "dirty", true); //"My house is dirty... so dirty... dirty"
var str3 = str.replaceAll("clean", "dirty", false); //"My house is dirty... so dirty... Clean"
var str4 = str.replaceAll(" clean", "", true); //"My house is... so..."
var str5 = str.replaceAll(undefined, "nothing"); //"My house is clean... so clean... Clean"
var str6 = str.replaceAll("nothing", undefined); //"My house is clean... so clean... Clean"
var str7 = str.replaceAll(); //"My house is clean... so clean... Clean"
var str8 = str.replaceAll("clean", 0); //"My house is 0... so 0... Clean", "Passing number on newToken, consider it as string"
var str9 = _str.replaceAll(15, "nothing"); //"There are 15 sheeps in the 2 ships transporting 14 chips"
Most of the times I used to copy the concept below:
while(str.indexOf(token) !== -1) {
str.replace(token, newToken);
}
But the major problem of this method is the recursivity. Let’s say you want to do the following:
"A str here".replaceAll("str", "string");
KABOOM, infinite loop and stucked browser. In the replaceAll above this kind of behavior do not occurs
And I saw already a lot of REGEX using normal replace like replace(new RegExp(“token”, “gi”), “newToken”), but it takes toooooo long.
UPDATE:
Looks like this.split(token).join(newToken) works better and is faster for a non ignoreCase situation, so I updated the code (needs to find a way to use native methods ignoring the case =()
Curti o seu código, e copiei ao embalo de Tarja! Mas mudei o fim colocando um return typeof token para o caso de dar erro eu saber que raio de token eu mandei pra lá.
Opa \,,/
o replaceAll não modifica a string original ele retorna a string modificada.
Se você mudar o return o código não surtirá efeito.
Para verificar o output do token eu recomendo usar a ferramenta web developer do navegador que vc está testando, você pode usar o console.log fazendo uma checkagem assim:
if(window.console && window.console.log) {
window.console.log(typeof token);
}
When ignoreCase is true, you should use ‘_token’ instead’ of ‘token’ within the while loop.
Actually it doesn’t matter if I use _token or token, both of them will have the same length. As a matter of design “token” is much more intuitive than “_token” cause the previous one is used just as a temporary var to check the lowercase of the original.