Самый быстрый способ замены всех экземпляров символа в строке

каков самый быстрый способ заменить все экземпляры строки / символа в строке в JavaScript? А while, a for - loop, регулярное выражение?

13 ответов


проще было бы использовать регулярное выражение с g флаг для замены всех экземпляров:

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

это заменит все вхождения foo С bar в строке str. Если у вас есть только строка, вы можете преобразовать ее в объект RegExp следующим образом:

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

попробуйте это 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);
} 

Он очень быстр, и он будет работать для всех этих условий что многие другие терпят неудачу на:

"x".replaceAll("x", "xyz");
// xyz

"x".replaceAll("", "xyz");
// xyzxxyz

"aA".replaceAll("a", "b", true);
// bb

"Hello???".replaceAll("?", "!");
// Hello!!!

Дайте мне знать, если вы можете разбить его, или у вас есть что-то лучше, но убедитесь, что он может пройти эти 4 теста.


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

newString теперь "Thas как strang"


также вы можете попробовать:

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

Вы можете использовать следующие:

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

или

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

это заменит все символы, которые не являются буквой или цифрами ('_'). Просто измените значение подчеркивания для того, что вы хотите заменить.


просто думая об этом из проблемы скорости, я считаю, что чувствительный к регистру пример, приведенный в ссылке выше, будет самым быстрым решением.

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 будет - Это проверка системы экстренного вещания."


Я думаю, что реальный ответ заключается в том, что он полностью зависит от того, как выглядят ваши входы. Я создал JsFiddle попробовать кучу этих и пару моих собственных против различных входов. Независимо от того, как я смотрю на результаты, я не вижу явного победителя.

  • RegExp не был самым быстрым в любом из тестовых случаев,но это было неплохо.
  • Split/Join подход кажется самым быстрым для разреженных замен.
  • этот, который я написал, кажется самый быстрый для малых входных сигналов и плотный замена:

    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;
    }
    

что самое быстрое, я не знаю, но я знаю, что самое читаемое - то, что самое короткое и простое. Даже если это немного медленнее, чем другое решение, его стоит использовать.

Так использовать:

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

и наслаждайтесь хорошим кодом, а не быстрее (хорошо... 1/100000 сек. это не разница) и уродливый. ;)


используйте объект Regex, как это

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

он заменит все возникновение " на '.


использовать replace() метод


я попробовал ряд этих предложений, поняв, что реализация, которую я написал об этом, вероятно, около 10 лет назад, на самом деле не работала полностью (неприятная ошибка производства в давно забытой системе, не так ли?!)... я заметил, что у тех, кого я пробовал (я не пробовал их все), была та же проблема, что и у меня, то есть они не заменяли каждое событие, только первое, по крайней мере, для моего тестового случая получения "теста"....txt "вниз к" тесту.тхт", заменив ".." с." "... может быть, я пропустил так regex ситуацию? Но я отвлекся...

Итак, я переписал свою реализацию следующим образом. Это довольно чертовски просто, хотя я подозреваю, что не самый быстрый, но я также не думаю, что разница будет иметь значение с современными двигателями JS, если вы не делаете это внутри жесткой петли, конечно, но это всегда так для чего-либо...

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;

}

надеюсь, что это поможет кому-то!


// 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 добавление дополнительного ответа-пользователя.электронная почта.заменить(/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)

демо