JavaScript replace/regex

Given this function:

function Repeater(template) {

    var repeater = {

        markup: template,

        replace: function(pattern, value) {
            this.markup = this.markup.replace(pattern, value);
        }

    };

    return repeater;

};

How do I make this.markup.replace() replace globally? Here's the problem. If I use it like this:

alert(new Repeater("$TEST_ONE $TEST_ONE").replace("$TEST_ONE", "foobar").markup);

The alert's value is "foobar $TEST_ONE".

If I change Repeater to the following, then nothing in replaced in Chrome:

function Repeater(template) {

    var repeater = {

        markup: template,

        replace: function(pattern, value) {
            this.markup = this.markup.replace(new RegExp(pattern, "gm"), value);
        }

    };

    return repeater;

};

...and the alert is $TEST_ONE $TEST_ONE.

Answers:

Answer

You need to double escape any RegExp characters (once for the slash in the string and once for the regexp):

  "$TESTONE $TESTONE".replace( new RegExp("\\$TESTONE","gm"),"foo")

Otherwise, it looks for the end of the line and 'TESTONE' (which it never finds).

Personally, I'm not a big fan of building regexp's using strings for this reason. The level of escaping that's needed could lead you to drink. I'm sure others feel differently though and like drinking when writing regexes.

Answer

In terms of pattern interpretation, there's no difference between the following forms:

  • /pattern/
  • new RegExp("pattern")

If you want to replace a literal string using the replace method, I think you can just pass a string instead of a regexp to replace.

Otherwise, you'd have to escape any regexp special characters in the pattern first - maybe like so:

function reEscape(s) {
    return s.replace(/([.*+?^$|(){}\[\]])/mg, "\\$1");
}

// ...

var re = new RegExp(reEscape(pattern), "mg");
this.markup = this.markup.replace(re, value);
Answer

Your regex pattern should have the g modifier:

var pattern = /[somepattern]+/g;

notice the g at the end. it tells the replacer to do a global replace.

Also you dont need to use the RegExp object you can construct your pattern as above. Example pattern:

var pattern = /[0-9a-zA-Z]+/g;

a pattern is always surrounded by / on either side - with modifiers after the final /, the g modifier being the global.

EDIT: Why does it matter if pattern is a variable? In your case it would function like this (notice that pattern is still a variable):

var pattern = /[0-9a-zA-Z]+/g;
repeater.replace(pattern, "1234abc");

But you would need to change your replace function to this:

this.markup = this.markup.replace(pattern, value);

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.