Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams
Closed 3 years ago .

The community reviewed whether to reopen this question 1 year ago and left it closed:

Needs details or clarity Add details and clarify the problem by editing this post .

A while and a for-loop both would run in O(n) with a simple algorithm. Not really sure what's the time complexity for Javascript regex-engine in this case, but my guess is its optimized enough to run in O(n) for a simple string match. Anurag Jan 22, 2010 at 10:33 This seems like micro-optimising to me - did performance profiling show up the string replacement to be the slowest part of your program? JBRWilkinson Jan 22, 2010 at 11:03 No, I didn't put my script through performance profiling, I was just making sure I'm using the fastest function available. Anriëtte Myburgh Aug 31, 2010 at 23:16 I've done a JSPerf comparing global regex and a for-loop: jsperf.com/javascript-replace-all . If I've written the tests appropriately, it looks like the answer is "it depends". Paul D. Waite Nov 13, 2012 at 12:22

The easiest would be to use a regular expression with g flag to replace all instances:

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

This will replace all occurrences of foo with bar in the string str. If you just have a string, you can convert it to a RegExp object like this:

var pattern = "foobar",
    re = new RegExp(pattern, "g");
                Warning: This does not work for strings containing newlines. XRegExp has a replace method that does the trick.
– kgriffs
                Jul 19, 2012 at 15:44
                I did user.email.replace(/./g,','), and the whole email got replaced with comas in the same number as characters in the email. Puzzled...
– Jared Tomaszewski
                Sep 30, 2013 at 20:13
                @JaredTomaszewski, the full stop (period) character in a regex stands for "any character". To signify an actual full stop, you'd need to precede it with a backslash i.e. user.email.replace(/\./g,',')
– Squig
                Oct 23, 2013 at 16:23
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);

It is very fast, and it will work for ALL these conditions that many others fail on:

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

Let me know if you can break it, or you have something better, but make sure it can pass these 4 tests.

This is quite good for replacing strings with unknown content, but his strings are fixed and does not need the complexity of escaping regular expressions. I upped this because I was searching for a replaceAll function. – NickSoft Nov 17, 2013 at 16:06 @jens All I'm saying is a giant CAVEAT EMPTOR. RegExes are super complicated, and a random internet answer that is supposed to solve someone's problem once and for all, but which very, very likely has some lurking bugs, is a poor answer indeed. We don't expect unit tests on answers that are obviously correct—of course not. But we DO expect that answers give the reader a proper understanding of their risks when an inexperienced programmer is likely to be misled into false confidence. My comment helps warn those beginners against trusting this untested, crazy code. – ErikE Sep 7, 2016 at 14:12 I've started adding unit tests for this function at the bottom of this test suite: github.com/agrothe/alphanumbers/blob/master/test/index.js – Andrew Grothe Sep 8, 2016 at 12:47 The behavior of "x".replaceAll("", "xyz"); seems like a bug to me. If I tried to replace empty string I'd really expect an error. – Slater Victoroff Jan 6, 2017 at 5:37 Since there’s now a standard replaceAll method, this answer overrides it now. Please do monkey patching correctly by checking the existence of a property first! – Sebastian Simon Mar 15, 2021 at 0:04 This routine is the fastest on Firefox but very slow on chrome: check my answer: stackoverflow.com/a/57697050/236062 – Zibri Aug 29, 2019 at 11:23 does this handle regular expression ? I guess. But for string to string replacement, this one is my favorite :) Very fast with firefox – yota Feb 23, 2017 at 8:00 @yota Yes. You can use regular expression. "12px (2) bar-456-foo 44".split(/\d/).join("#") – Vlada Feb 24, 2017 at 16:15 This is perfect for most simple cases. Works great in a nice little function like: function replaceAll( s, f, r ){ return s.split( f ).join( r ); }. Or if you think RegEx is faster: function replaceAll( s, f, r ){ f = RegExp( f, 'gi' ); return s.replace( f, r ); }. Then just do foo = replaceAll( 'aaa', 'a', 'b' );. – Beejor Jul 18, 2017 at 2:59 If your needle is some variable that contains one or more regex reserved characters, then the methods of the other answers can do unexpected replacements. The good thing about this method is that it treats all characters the same way. – Quinten Jul 15, 2021 at 9:36

Just thinking about it from a speed issue I believe the case sensitive example provided in the link above would be by far the fastest solution.

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 would be "This is a test of the emergency broadcast system."

I think the real answer is that it completely depends on what your inputs look like. I created a JsFiddle to try a bunch of these and a couple of my own against various inputs. No matter how I look at the results, I see no clear winner.

  • RegExp wasn't the fastest in any of the test cases, but it wasn't bad either.
  • Split/Join approach seems fastest for sparse replacements.
  • This one I wrote seems fastest for small inputs and dense replacements:

    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;
                    Another consideration to factor in is that the split/join approach is the simplest, shortest, most to-the-point approach, making it the most likely candidate for future browsers to internally optimize it into something several times faster (e.g. instead of creating a new array and a new string, it would instead just search through & copy-n-paste it linearly similar to a regular expression) during JIST compilation.
    – Jack G
                    Aug 3, 2017 at 1:12
    

    What's the fastest I don't know, but I know what's the most readable - that what's shortest and simplest. Even if it's a little bit slower than other solution it's worth to use.

    So use:

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

    And enjoy good code instead of faster (well... 1/100000 sec. is not a difference) and ugly one. ;)

    I just coded a benchmark and tested the first 3 answers. It seems that for short strings (<500 characters)
    the third most voted answer is faster than the second most voted one.

    For long strings (add ".repeat(300)" to the test string) the faster is answer 1 followed by the second and the third.

    Note:

    The above is true for browsers using v8 engine (chrome/chromium etc).
    With firefox (SpiderMonkey engine) the results are totally different
    Check for yourselves!! Firefox with the third solution seems to be
    more than 4.5 times faster than Chrome with the first solution... crazy :D

    ((new Date().getTime() - t) < ms); z++) f(num); return (z / ms) } // returns how many times the function was run in "ms" milliseconds. function benchmark() { function compare(a, b) { if (a[1] > b[1]) { return -1; if (a[1] < b[1]) { return 1; return 0; // functions function replace1(s) { s.replace(/foo/g, "bar") String.prototype.replaceAll2 = function(_f, _r){ 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; 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); function replace2(s) { s.replaceAll("foo", "bar") function replace3(s) { s.split('foo').join('bar'); function replace4(s) { s.replaceAll2("foo", "bar") funcs = [ [replace1, 0], [replace2, 0], [replace3, 0], [replace4, 0] funcs.forEach((ff) => { console.log("Benchmarking: " + ff[0].name); ff[1] = time_function(2500, ff[0], "foOfoobarBaR barbarfoobarf00".repeat(10)); console.log("Score: " + ff[1]); return funcs.sort(compare); return benchmark; log("Starting benchmark...\n"); res = benchmark(); console.log("Winner: " + res[0][0].name + " !!!"); count = 1; res.forEach((r) => { log((count++) + ". " + r[0].name + " score: " + Math.floor(10000 * r[1] / res[0][1]) / 100 + ((count == 2) ? "% *winner*" : "% speed of winner.") + " (" + Math.round(r[1] * 100) / 100 + ")"); log("\nWinner code:\n"); log(res[0][0].toString());
    <textarea rows="50" cols="80" style="font-size: 16; resize:none; border: none;" id="log"></textarea>
    Chrome/Linux Ubuntu 64:
    1. replace1 score: 100% *winner* (766.18)
    2. replace4 score: 99.07% speed of winner. (759.11)
    3. replace3 score: 68.36% speed of winner. (523.83)
    4. replace2 score: 59.35% speed of winner. (454.78)
    Firefox/Linux Ubuntu 64
    1. replace3 score: 100% *winner* (3480.1)
    2. replace1 score: 13.06% speed of winner. (454.83)
    3. replace4 score: 9.4% speed of winner. (327.42)
    4. replace2 score: 4.81% speed of winner. (167.46)
    

    Nice mess uh?

    Took the liberty of adding more test results

    Chrome/Windows 10
    1. replace1 score: 100% *winner* (742.49)
    2. replace4 score: 85.58% speed of winner. (635.44)
    3. replace2 score: 54.42% speed of winner. (404.08)
    4. replace3 score: 50.06% speed of winner. (371.73)
    Firefox/Windows 10
    1. replace3 score: 100% *winner* (2645.18)
    2. replace1 score: 30.77% speed of winner. (814.18)
    3. replace4 score: 22.3% speed of winner. (589.97)
    4. replace2 score: 12.51% speed of winner. (331.13)
    Edge/Windows 10
    1. replace1 score: 100% *winner* (1251.24)
    2. replace2 score: 46.63% speed of winner. (583.47)
    3. replace3 score: 44.42% speed of winner. (555.92)
    4. replace4 score: 20% speed of winner. (250.28)
    

    Chrome on Galaxy Note 4

    1. replace4 score: 100% *winner* (99.82)
    2. replace1 score: 91.04% speed of winner. (90.88)
    3. replace3 score: 70.27% speed of winner. (70.15)
    4. replace2 score: 38.25% speed of winner. (38.18)
    

    I tried a number of these suggestions after realizing that an implementation I had written of this probably close to 10 years ago actually didn't work completely (nasty production bug in an long-forgotten system, isn't that always the way?!)... what I noticed is that the ones I tried (I didn't try them all) had the same problem as mine, that is, they wouldn't replace EVERY occurrence, only the first, at least for my test case of getting "test....txt" down to "test.txt" by replacing ".." with "."... maybe I missed so regex situation? But I digress...

    So, I rewrote my implementation as follows. It's pretty darned simple, although I suspect not the fastest but I also don't think the difference will matter with modern JS engines, unless you're doing this inside a tight loop of course, but that's always the case for anything...

    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;
    

    Hope that helps someone!

    // 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;
                    This routine is the second fastest on Chrome but it takes 4.5 times  the speed of fastest on Firefox, check my answer: stackoverflow.com/a/57697050/236062
    – Zibri
                    Aug 29, 2019 at 11:20
                    @Dr. Hfuhruhurr - it can also replace all matches, if the /g option is used, as specified by the replace() method documentation (w3schools.com/jsref/jsref_obj_regexp.asp for example). Just because I did not explicitly mention the /g option does not make my answer any less valid.
    – Franci Penov
                    Nov 4, 2010 at 16:15
    

    @Gumbo adding extra answer - user.email.replace(/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)
    
  •