Categories
javascript regex

How do you use a variable in a regular expression?

1762

I would like to create a String.replaceAll() method in JavaScript and I’m thinking that using a regex would be most terse way to do it. However, I can’t figure out how to pass a variable in to a regex. I can do this already which will replace all the instances of "B" with "A".

"ABABAB".replace(/B/g, "A");

But I want to do something like this:

String.prototype.replaceAll = function(replaceThis, withThis) {
    this.replace(/replaceThis/g, withThis);
};

But obviously this will only replace the text "replaceThis"…so how do I pass this variable in to my regex string?

2

2256

Instead of using the /regex\d/g syntax, you can construct a new RegExp object:

var replace = "regex\\d";
var re = new RegExp(replace,"g");

You can dynamically create regex objects this way. Then you will do:

"mystring1".replace(re, "newstring");

3

  • 316

    If you need to use an expression like /\/word\:\w*$/, be sure to escape your backslashes: new RegExp( '\\/word\\:\\w*$' ).

    Nov 9, 2010 at 23:04

  • 50

    The question suggests that the RegEx is only used to do a constant string replacement. So this is answer is wrong as it would fail if the string contains RegEx meta characters. Sad it is voted this high, will make many headaches…

    – dronus

    Feb 12, 2014 at 20:32

  • 30

    An example of this passing a variable would make this a good answer. I’m still struggling after reading this.

    – Goose

    Jun 5, 2015 at 18:44

258

As Eric Wendelin mentioned, you can do something like this:

str1 = "pattern"
var re = new RegExp(str1, "g");
"pattern matching .".replace(re, "regex");

This yields "regex matching .". However, it will fail if str1 is ".". You’d expect the result to be "pattern matching regex", replacing the period with "regex", but it’ll turn out to be…

regexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregex

This is because, although "." is a String, in the RegExp constructor it’s still interpreted as a regular expression, meaning any non-line-break character, meaning every character in the string. For this purpose, the following function may be useful:

 RegExp.quote = function(str) {
     return str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
 };

Then you can do:

str1 = "."
var re = new RegExp(RegExp.quote(str1), "g");
"pattern matching .".replace(re, "regex");

yielding "pattern matching regex".

10

  • 5

    You know that the first parameter to replace can be a normal string and don’t have to be a regexp? str1 = “.”; alert(“pattern matching .”.replace(str1, “string”));

    – some

    Jan 30, 2009 at 10:31

  • @some: of course. That’s because the above example is trivial. When you need to search for or replace a pattern combined with a regular string, do str.match(new RegExp(“https?://” + RegExp.escape(myDomainName)), for instance. It’s annoying that the escape function is not built in.

    Jan 30, 2009 at 19:57

  • (continued) Plus, apparentl JC Grubbs required a global replace; implementing a global replace with String.replace(String, String) could be slow for large input. I’m just saying, the top two solutions are buggy, and will fail unexpected on certain input.

    Jan 30, 2009 at 20:00

  • 5

    developer.mozilla.org/en-US/docs/JavaScript/Guide/… offers a similar function, but they exclude -, and include =!:/.

    – chbrown

    Dec 15, 2012 at 21:12

  • 8

    The correct term is “escape”, not “quote”. Just BTW.

    Dec 4, 2015 at 5:19

139

"ABABAB".replace(/B/g, "A");

As always: don’t use regex unless you have to. For a simple string replace, the idiom is:

'ABABAB'.split('B').join('A')

Then you don’t have to worry about the quoting issues mentioned in Gracenotes’s answer.

9

  • 17

    And have you measured that this is faster than regex?

    – Mitar

    Apr 10, 2013 at 3:12

  • 3

    This seems preferable, especially when needing to match on special regex characters like ‘.’

    – Krease

    Apr 24, 2013 at 18:41

  • 1

    Uhm… Doesn’t split take a RegExp too; if so, wouldn’t it cause the same problem ? Anyway… .split().join() may be slower on some platforms, because it’s two operations, whereas .replace() is one operation and may be optimized.

    – user1985657

    Jun 12, 2013 at 22:47


  • 5

    @PacMan–: both split and replace can take either a string or a RegExp object. The problem that replace has that split doesn’t is that when you use a string you only get a single replacement.

    – bobince

    Jun 13, 2013 at 9:05

  • 2