Méthode la plus rapide pour remplacer toutes les occurrences d'un caractère dans une chaîne
Quel est le moyen le plus rapide pour remplacer toutes les instances d'une chaîne/caractère dans une chaîne en JavaScript? Un while
, un for
en boucle, une expression régulière?
13 réponses
le plus simple serait d'utiliser une expression régulière avec g
pour remplacer toutes les instances:
str.replace(/foo/g, "bar")
remplacer toutes les occurrences de foo
par bar
dans la chaîne de caractères str
. Si vous avez juste une chaîne, vous pouvez la convertir en un objet RegExp comme ceci:
var pattern = "foobar",
re = new RegExp(pattern, "g");
essayez ce 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);
}
il est très rapide, et il fonctionnera pour toutes ces conditions que beaucoup d'autres échouent sur:
"x".replaceAll("x", "xyz");
// xyz
"x".replaceAll("", "xyz");
// xyzxxyz
"aA".replaceAll("a", "b", true);
// bb
"Hello???".replaceAll("?", "!");
// Hello!!!
Laissez-moi savoir si vous pouvez rompre, ou si vous avez quelque chose de mieux, mais assurez-vous qu'il peut passer ces 4 tests.
var mystring = 'This is a string';
var newString = mystring.replace(/i/g, "a");
newString est maintenant 'Thas comme un strang'
vous pouvez utiliser ce qui suit:
newStr = str.replace(/[^a-z0-9]/gi, '_');
ou
newStr = str.replace(/[^a-zA-Z0-9]/g, '_');
cela va remplacer tous les caractères qui ne sont pas des lettres ou des chiffres à ('_'). Changez simplement la valeur de underscore pour ce que vous voulez remplacer.
rien qu'en y réfléchissant à partir d'une question de vitesse, je crois que l'exemple sensible au cas fourni dans le lien ci-dessus serait de loin la solution la plus rapide.
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 serait "Ceci est un test du système de diffusion d'urgence."
je pense que la vraie réponse est qu'elle dépend complètement de ce à quoi vos entrées ressemblent. J'ai créé un JsFiddle pour essayer un tas de ceux-ci et un couple de mes propres contre diverses entrées. Peu importe comment je regarde les résultats, Je ne vois aucun gagnant clair.
- RegExp n'était pas le plus rapide dans aucun des cas, mais il n'était pas mauvais non plus.
- Split / Join approach semble le plus rapide pour les remplacements épars.
-
celui que j'ai écrit semble le plus rapide pour les petites entrées et dense remplacements:
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; }
ce qui est le plus rapide Je ne sais pas, mais je sais ce qui est le plus lisible - que ce qui est le plus court et le plus simple. Même s'il est un peu plus lent que d'autres solutions, il vaut la peine d'utiliser.
ainsi utiliser:
"string".replace("a", "b");
"string".replace(/abc?/g, "def");
et profiter de bon code au lieu de plus rapide (bien... 1/100000 sec. n'est pas une différence) et laide. ;)
utiliser objet Regex comme ceci
var regex = new RegExp('"', 'g');
str = str.replace(regex, '\'');
il remplacera toutes les occurrences de "
par '
.
utilisez la méthode replace()
de l'objet String
.
comme mentionné dans la réponse sélectionnée, le drapeau /g doit être utilisé dans le regex, afin de remplacer toutes les instances du substrat dans la chaîne.
j'ai essayé un certain nombre de ces suggestions après avoir réalisé qu'une implémentation que j'avais écrite il y a probablement près de 10 ans ne fonctionnait pas complètement (bogue de production désagréable dans un système oublié depuis longtemps, n'est-ce pas toujours le cas?!)... ce que j'ai remarqué, c'est que ceux que j'ai essayés (Je ne les ai pas tous essayés) avaient le même problème que le mien, c'est-à-dire qu'ils ne remplaceraient pas chaque occurrence, seulement le premier, au moins pour mon cas de test d'obtenir "test....txt" à "tester.txt" par remplacer." ." avec." "... peut-être que j'ai manqué la situation de So regex? Mais je m'égare...
donc, j'ai réécrit mon implémentation comme suit. C'est assez simple, bien que je ne soupçonne pas le plus rapide, mais je ne pense pas que la différence sera importante avec les moteurs js modernes, à moins que vous ne le fassiez dans une boucle étroite bien sûr, mais c'est toujours le cas pour n'importe quoi...
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;
}
Espère que ça aide quelqu'un!
// Find, Replace, Case
// i.e "Test to see if this works? (Yes|No)".replaceAll('(Yes|No)', 'Yes!');
// i.e.2 "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;
};
@Gumbo ajouter réponse supplémentaire-utilisateur.courriel.remplacer (/foo / gi,"bar");
/foo/g - Refers to the all string to replace matching the case sensitive
/foo/gi - Refers to the without case sensitive and replace all For Eg: (Foo, foo, FoO, fOO)