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?

492
demandé sur thorn 2010-01-22 13:26:06

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");
880
répondu Gumbo 2016-11-19 00:40:41

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.

122
répondu qwerty 2014-09-27 05:04:27
var mystring = 'This is a string';
var newString = mystring.replace(/i/g, "a");

newString est maintenant 'Thas comme un strang'

77
répondu Sani Singh Huttunen 2010-01-22 11:02:49

vous pouvez aussi essayer:

string.split('foo').join('bar');
28
répondu Vlada 2015-12-25 23:13:09

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.

9
répondu ssamuel68 2013-02-22 16:30:49

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

9
répondu ADamienS 2014-03-03 21:14:31

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;
    }
    
7
répondu Rick Velde 2016-07-31 03:31:55

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. ;)

6
répondu Crozin 2010-01-22 10:31:38

utiliser objet Regex comme ceci

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

il remplacera toutes les occurrences de " par ' .

6
répondu Neel Kamal 2013-10-15 13:37:31

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.

6
répondu Franci Penov 2017-09-08 00:28:49

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!

5
répondu Frank W. Zammetti 2012-06-13 17:02:42
// 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;
};
2
répondu MadHatter 2014-04-22 04:20:40

@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)

DÉMO

0
répondu Surya R Praveen 2018-09-26 12:03:11