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 likes to explore JS and FP techniques. He's written books, taught, and spoken publicly. He's currently helping build a culture of engineering excellence for his employer.

Recent Features

  • By
    5 Awesome New Mozilla Technologies You&#8217;ve Never Heard Of

    My trip to Mozilla Summit 2013 was incredible.  I've spent so much time focusing on my project that I had lost sight of all of the great work Mozillians were putting out.  MozSummit provided the perfect reminder of how brilliant my colleagues are and how much...

  • By
    Serving Fonts from CDN

    For maximum performance, we all know we must put our assets on CDN (another domain).  Along with those assets are custom web fonts.  Unfortunately custom web fonts via CDN (or any cross-domain font request) don't work in Firefox or Internet Explorer (correctly so, by spec) though...

Incredible Demos

  • By
    Redacted Font

    Back when I created client websites, one of the many things that frustrated me was the initial design handoff.  It would always go like this: Work hard to incorporate client's ideas, dream up awesome design. Create said design, using Lorem Ipsum text Send initial design concept to the client...

  • By
    MooTools PulseFade Plugin

    I was recently driven to create a MooTools plugin that would take an element and fade it to a min from a max for a given number of times. Here's the result of my Moo-foolery. The MooTools JavaScript Options of the class include: min: (defaults to .5) the...

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!