Using String Replace in JavaScript

By  on  

This is a quickie simple post on JavaScript techniques. We're going to cover how to use the regular expression driven replace(..) with JavaScript string values.

All string values have a replace(..) method available to them. This method allows you to pass a regular expression (or a string that will be interpreted as the pattern for a dynamically-created regular expression!) to represent what should be found in the main string value for replacing.

Single vs Global

Consider:

var a = "The quick brown fox jumped over the lazy dog.";

var pattern = /the/i;

a.replace( pattern, "THE" );
// THE quick brown fox jumped over the lazy dog.

You can see only the first "The" was replaced. Many developers just leave that fact as is, and never ask, "Why?".

Well, it's because you didn't use a global regular expression (that is, with the g flag), so clearly JS only applies the expression in a single context. See:

var a = "The quick brown fox jumped over the lazy dog.";

var pattern = /the/ig; // notice "g" here now!

a.replace( pattern, "THE" );
// THE quick brown fox jumped over THE lazy dog.

The replacer string ("THE" in our example) can include certain special commands, such as "$1" for dropping in the value of the first ( ) group match (there is none in our example!).

function As Replacer

What if you wanted to do a more sophisticated replacement, like for instance capitalizing any of a set of words found, using a pattern like this?

var pattern = /quick|brown|lazy/ig;

Obviously, hard-coding the "THE" replacer string won't work now!

But it's a little known fact that the replacer can be a function instead. For example:

var a = "The quick brown fox jumped over the lazy dog.";

var pattern = /quick|brown|lazy/ig;

a.replace( pattern, function replacer(match){
    return match.toUpperCase();
} );
// The QUICK BROWN fox jumped over the LAZY dog.

The function replacer gets several arguments. The first is always the matched string, which is often all you want/need. If the pattern has any ( ) group match(es), those will be passed as the next argument(s). The next argument will be the numeric indexed position of the match in the bigger string.

The final argument is the full original string being replaced against, not the current in-progress string value that's being processed.

Another place where the function replacer comes in handy is if the string you're replacing with already has some of the special replacer string command sequences, like "$1" instance, because the returned value from the function is not interpolated like the regular string replacer is:

var prices = {
    "pr_1": "$1.99",
    "pr_2": "$9.99",
    "pr_3": "$5.00"
};

var template = ".."; // some ecommerce page template

template.replace(
    /(<span id=")(.*?)(">)(<\/span>)/g,
    function(match,$1,$2,$3,$4){
        return $1 + $2 + $3 + prices[$2] + $4;
    }
);

The value "$1.99" couldn't have been used as a string replacer because "$1" would have been interpreted as the first match. The only other option is to pre-escape your string replacer values, like "$$1.99", but no one wants to do that, so the function replacer is better.

Summary

Regular expression string replace is a more powerful mechanism than most developers give JS credit for.

Global /g regular expressions and function replacer values are just some of the useful but not as well known features of regular expression patterns and replace(..).

Kyle Simpson

About Kyle Simpson

Kyle Simpson is an Open Web Evangelist from Austin, TX, passionate about all things JavaScript. He's an author, workshop trainer, tech speaker, and OSS contributor/leader.

Recent Features

  • By
    JavaScript Promise API

    While synchronous code is easier to follow and debug, async is generally better for performance and flexibility. Why "hold up the show" when you can trigger numerous requests at once and then handle them when each is ready?  Promises are becoming a big part of the JavaScript world...

  • By
    fetch API

    One of the worst kept secrets about AJAX on the web is that the underlying API for it, XMLHttpRequest, wasn't really made for what we've been using it for.  We've done well to create elegant APIs around XHR but we know we can do better.  Our effort to...

Incredible Demos

  • By
    GitHub-Style Sliding Links

    GitHub seems to change a lot but not really change at all, if that makes any sense; the updates come often but are always fairly small. I spotted one of the most recent updates on the pull request page. Links to long branch...

  • By
    CSS Filters

    CSS filter support recently landed within WebKit nightlies. CSS filters provide a method for modifying the rendering of a basic DOM element, image, or video. CSS filters allow for blurring, warping, and modifying the color intensity of elements. Let's have...

Discussion

  1. Nice explanation. Thanks.

  2. Asmor

    How have I not known about this sooner? Thanks!

  3. Nice David, I`ve gisted a generalization some years ago that use the String.replace callback function. I find it very useful and just wanted to share it:
    https://gist.github.com/fedeghe/7562904

  4. Sorry… nice explanation Kyle!!!

  5. Nice post! The replace with callback fuction will be very useful for me!

  6. David

    Wow, thanks Kyle. I can already picture where I could have used the function replacer in my code.
    Fun fact, “The quick brown fox jumped over the lazy dog” has no ‘s’.

  7. Good post – thanks Kyle. Do you ever use libraries like string.js for this sort of thing?

  8. HapHazzard

    down and dirty. fast too.

    str = str.split('string to replace').join('string to insert')
  9. Stefan

    The function bit was so incredibly useful. Thank you! :)

  10. Fagner Brack

    FWIW, I have recently implemented a very simple way to replace strings with a big legibility trade-off over performance, see http:// github.com/FagnerMartinsBrack/str-replace

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!