How do you use a variable in a regular expression?
JavascriptRegexJavascript Problem Overview
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?
Javascript Solutions
Solution 1 - Javascript
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");
Solution 2 - Javascript
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"
.
Solution 3 - Javascript
> "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.
Solution 4 - Javascript
If you want to get all occurrences (g
), be case insensitive (i
), and use boundaries so that it isn't a word within another word (\\b
):
re = new RegExp(`\\b${replaceThis}\\b`, 'gi');
Example:
let inputString = "I'm John, or johnny, but I prefer john.";
let replaceThis = "John";
let re = new RegExp(`\\b${replaceThis}\\b`, 'gi');
console.log(inputString.replace(re, "Jack")); // I'm Jack, or johnny, but I prefer Jack.
Solution 5 - Javascript
This:
var txt=new RegExp(pattern,attributes);
is equivalent to this:
var txt=/pattern/attributes;
Solution 6 - Javascript
For anyone looking to use a variable with the match method, this worked for me:
var alpha = 'fig';
'food fight'.match(alpha + 'ht')[0]; // fight
Solution 7 - Javascript
this.replace( new RegExp( replaceThis, 'g' ), withThis );
Solution 8 - Javascript
You need to build the regular expression dynamically and for this you must use the new RegExp(string)
constructor with escaping.
There is a built-in function in jQuery UI autocomplete widget called $.ui.autocomplete.escapeRegex
:
> It'll take a single string argument and escape all regex characters,
> making the result safe to pass to new RegExp()
.
If you are not using jQuery UI you can copy its definition from the source:
function escapeRegex( value ) {
return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
}
And use it like this:
"[z-a][z-a][z-a]".replace(new RegExp(escapeRegex("[z-a]"), "g"), "[a-z]");
// escapeRegex("[z-a]") -> "\[z\-a\]"
// new RegExp(escapeRegex("[z-a]"), "g") -> /\[z\-a\]/g
// end result -> "[a-z][a-z][a-z]"
Solution 9 - Javascript
String.prototype.replaceAll = function (replaceThis, withThis) {
var re = new RegExp(replaceThis,"g");
return this.replace(re, withThis);
};
var aa = "abab54..aba".replaceAll("\\.", "v");
Test with this tool
Solution 10 - Javascript
String.prototype.replaceAll = function(a, b) {
return this.replace(new RegExp(a.replace(/([.?*+^$[\]\\(){}|-])/ig, "\\$1"), 'ig'), b)
}
Test it like:
var whatever = 'Some [b]random[/b] text in a [b]sentence.[/b]'
console.log(whatever.replaceAll("[", "<").replaceAll("]", ">"))
Solution 11 - Javascript
And the CoffeeScript version of Steven Penny's answer, since this is #2 Google result....even if CoffeeScript is just JavaScript with a lot of characters removed...;)
baz = "foo"
filter = new RegExp(baz + "d")
"food fight".match(filter)[0] // food
And in my particular case:
robot.name = hubot
filter = new RegExp(robot.name)
if msg.match.input.match(filter)
console.log "True!"
Solution 12 - Javascript
To satisfy my need to insert a variable/alias/function into a Regular Expression, this is what I came up with:
oldre = /xx\(""\)/;
function newre(e){
return RegExp(e.toString().replace(/\//g,"").replace(/xx/g, yy), "g")
};
String.prototype.replaceAll = this.replace(newre(oldre), "withThis");
where 'oldre' is the original regexp that I want to insert a variable, 'xx' is the placeholder for that variable/alias/function, and 'yy' is the actual variable name, alias, or function.
Solution 13 - Javascript
You can use a string as a regular expression. Don’t forget to use new RegExp.
Example:
var yourFunction = new RegExp(
'^-?\\d+(?:\\.\\d{0,' + yourVar + '})?'
)
Solution 14 - Javascript
Here's another replaceAll implementation:
String.prototype.replaceAll = function (stringToFind, stringToReplace) {
if ( stringToFind == stringToReplace) return this;
var temp = this;
var index = temp.indexOf(stringToFind);
while (index != -1) {
temp = temp.replace(stringToFind, stringToReplace);
index = temp.indexOf(stringToFind);
}
return temp;
};
Solution 15 - Javascript
You can use this if $1
does not work for you:
var pattern = new RegExp("amman", "i");
"abc Amman efg".replace(pattern, "<b>" + "abc Amman efg".match(pattern)[0] + "</b>");
Solution 16 - Javascript
While you can make dynamically-created RegExp's (as per the other responses to this question), I'll echo my comment from a similar post: The functional form of String.replace() is extremely useful and in many cases reduces the need for dynamically-created RegExp objects. (which are kind of a pain 'cause you have to express the input to the RegExp constructor as a string rather than use the slashes /[A-Z]+/ regexp literal format)
Solution 17 - Javascript
None of these answers were clear to me. I eventually found a good explanation at How to use a variable in replace function of JavaScript
The simple answer is:
var search_term = new RegExp(search_term, "g");
text = text.replace(search_term, replace_term);
For example:
$("button").click(function() {
Find_and_replace("Lorem", "Chocolate");
Find_and_replace("ipsum", "ice-cream");
});
function Find_and_replace(search_term, replace_term) {
text = $("textbox").html();
var search_term = new RegExp(search_term, "g");
text = text.replace(search_term, replace_term);
$("textbox").html(text);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textbox>
Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum
</textbox>
<button>Click me</button>
Solution 18 - Javascript
This self calling function will iterate over replacerItems using an index, and change replacerItems[index] globally on the string with each pass.
const replacerItems = ["a", "b", "c"];
function replacer(str, index){
const item = replacerItems[index];
const regex = new RegExp(`[${item}]`, "g");
const newStr = str.replace(regex, "z");
if (index < replacerItems.length - 1) {
return replacer(newStr, index + 1);
}
return newStr;
}
// console.log(replacer('abcdefg', 0)) will output 'zzzdefg'
Solution 19 - Javascript
You can always use indexOf
repeatedly:
String.prototype.replaceAll = function(substring, replacement) {
var result = '';
var lastIndex = 0;
while(true) {
var index = this.indexOf(substring, lastIndex);
if(index === -1) break;
result += this.substring(lastIndex, index) + replacement;
lastIndex = index + substring.length;
}
return result + this.substring(lastIndex);
};
This doesn’t go into an infinite loop when the replacement contains the match.
Solution 20 - Javascript
One way to implement is by taking the value from a text field which is the one you want to replace and another is the "replace with" text field, getting the value from text-field in a variable and setting the variable to RegExp function to further replace. In my case I am using jQuery, but you can also do it by only JavaScript too.
JavaScript code:
var replace =document.getElementById("replace}"); // getting a value from a text field with I want to replace
var replace_with = document.getElementById("with"); //Getting the value from another text fields with which I want to replace another string.
var sRegExInput = new RegExp(replace, "g");
$("body").children().each(function() {
$(this).html($(this).html().replace(sRegExInput,replace_with));
});
This code is on the Onclick event of a button, and you can put this in a function to call.
So now you can pass a variable in the replace function.
Solution 21 - Javascript
For multiple replace without regular expressions I went with the following:
let str = "I am a cat man. I like cats";
let find = "cat";
let replace = "dog";
// Count how many occurrences there are of the string to find
// inside the str to be examined.
let findCount = str.split(find).length - 1;
let loopCount = 0;
while (loopCount < findCount)
{
str = str.replace(find, replace);
loopCount = loopCount + 1;
}
console.log(str);
// I am a dog man. I like dogs
Solution 22 - Javascript
As a relative JavaScript novice, the accepted answer https://stackoverflow.com/a/494046/1904943 is noted / appreciated, but it is not very intuitive.
Here is a simpler interpretation, by example (using a simple JavaScript IDE).
myString = 'apple pie, banana loaf';
console.log(myString.replaceAll(/pie/gi, 'PIE'))
// apple PIE, banana loaf
console.log(myString.replaceAll(/\bpie\b/gi, 'PIE'))
// apple PIE, banana loaf
console.log(myString.replaceAll(/pi/gi, 'PIE'))
// apple PIEe, banana loaf
console.log(myString.replaceAll(/\bpi\b/gi, 'PIE'))
// [NO EFFECT] apple pie, banana loaf
const match_word = 'pie';
console.log(myString.replaceAll(/match_word/gi, '**PIE**'))
// [NO EFFECT] apple pie, banana loaf
console.log(myString.replaceAll(/\b`${bmatch_word}`\b/gi, '**PIE**'))
// [NO EFFECT] apple pie, banana loaf
// ----------------------------------------
// ... new RegExp(): be sure to \-escape your backslashes: \b >> \\b ...
const match_term = 'pie';
const match_re = new RegExp(`(\\b${match_term}\\b)`, 'gi')
console.log(myString.replaceAll(match_re, 'PiE'))
// apple PiE, banana loaf
console.log(myString.replace(match_re, '**PIE**'))
// apple **PIE**, banana loaf
console.log(myString.replaceAll(match_re, '**PIE**'))
// apple **PIE**, banana loaf
Application
E.g.: replacing (color highlighting) words in string / sentence, [optionally] if the search term matches a more than a user-defined proportion of the matched word.
Note: original character case of matched term is retained. hl
: highlight; re
: regex | regular expression
mySentence = "Apple, boOk? BOoks; booKEd. BookMark, 'BookmarkeD', bOOkmarks! bookmakinG, Banana; bE, BeEn, beFore."
function replacer(mySentence, hl_term, hl_re) {
console.log('mySentence [raw]:', mySentence)
console.log('hl_term:', hl_term, '| hl_term.length:', hl_term.length)
cutoff = hl_term.length;
console.log('cutoff:', cutoff)
// `.match()` conveniently collects multiple matched items
// (including partial matches) into an [array]
const hl_terms = mySentence.toLowerCase().match(hl_re, hl_term);
if (hl_terms == null) {
console.log('No matches to hl_term "' + hl_term + '"; echoing input string then exiting ...')
return mySentence;
}
console.log('hl_terms:', hl_terms)
for (let i = 0; i < hl_terms.length; i++) {
console.log('----------------------------------------')
console.log('[' + i + ']:', hl_terms[i], '| length:', hl_terms[i].length, '| parseInt(0.7(length)):', parseInt(0.7*hl_terms[i].length))
// TEST: if (hl_terms[i].length >= cutoff*10) {
if (cutoff >= parseInt(0.7 * hl_terms[i].length)) {
var match_term = hl_terms[i].toString();
console.log('matched term:', match_term, '[cutoff length:', cutoff, '| 0.7(matched term length):', parseInt(0.7 * hl_terms[i].length))
const match_re = new RegExp(`(\\b${match_term}\\b)`, 'gi')
mySentence = mySentence.replaceAll(match_re, '<font style="background:#ffe74e">$1</font>');
}
else {
var match_term = hl_terms[i].toString();
console.log('NO match:', match_term, '[cutoff length:', cutoff, '| 0.7(matched term length):', parseInt(0.7 * hl_terms[i].length))
}
}
return mySentence;
}
// TESTS:
// const hl_term = 'be';
// const hl_term = 'bee';
// const hl_term = 'before';
// const hl_term = 'book';
const hl_term = 'bookma';
// const hl_term = 'Leibniz';
// This regex matches from start of word:
const hl_re = new RegExp(`(\\b${hl_term}[A-z]*)\\b`, 'gi')
mySentence = replacer(mySentence, hl_term, hl_re);
console.log('mySentence [processed]:', mySentence)
Output
mySentence [raw]: Apple, boOk? BOoks; booKEd. BookMark, 'BookmarkeD',
bOOkmarks! bookmakinG, Banana; bE, BeEn, beFore.
hl_term: bookma | hl_term.length: 6
cutoff: 6
hl_terms: Array(4) [ "bookmark", "bookmarked", "bookmarks", "bookmaking" ]
----------------------------------------
[0]: bookmark | length: 8 | parseInt(0.7(length)): 5
matched term: bookmark [cutoff length: 6 | 0.7(matched term length): 5
----------------------------------------
[1]: bookmarked | length: 10 | parseInt(0.7(length)): 7
NO match: bookmarked [cutoff length: 6 | 0.7(matched term length): 7
----------------------------------------
[2]: bookmarks | length: 9 | parseInt(0.7(length)): 6
matched term: bookmarks [cutoff length: 6 | 0.7(matched term length): 6
----------------------------------------
[3]: bookmaking | length: 10 | parseInt(0.7(length)): 7
NO match: bookmaking [cutoff length: 6 | 0.7(matched term length): 7
mySentence [processed]: Apple, boOk? BOoks; booKEd.
<font style="background:#ffe74e">BookMark</font>, 'BookmarkeD',
<font style="background:#ffe74e">bOOkmarks</font>! bookmakinG,
Banana; bE, BeEn, beFore.
Solution 23 - Javascript
If you pass the variable with the correct syntax, you can do this like so with the code below.
This has the added benefit of using the flags in the same variable.
Also you don't have to double escape \
in the regular expression when it comes to \w
, etc.
var str = 'regexVariable example: This is my example of RegExp replacing with a regexVariable.'
var reVar = /(.*?)(regex\w+?iable)(.+?)/gi;
var resStr = str.replace(new RegExp(reVar), '$1 :) :) :) $2 :) :) :)$3');
console.log(resStr);
// Returns:
// :) :) :) regexVariable :) :) :) example: This is my example of RegExp replacing with a :) :) :) regexVariable :) :) :).
The prototype version as per the OP's example:
var str = 'regexVariable prototype: This is my example of RegExp replacing with a regexVariable.'
String.prototype.regexVariable = function(reFind, reReplace) {
return str.replace(new RegExp(reFind), reReplace);
}
var reVar = /(.*?)(regex\w+?iable)(.+?)/gi;
console.log(str.regexVariable(reVar, '$1 :) :) :) $2 :) :) :)$3'));
// Returns:
// :) :) :) regexVariable :) :) :) prototype: This is my example of replacing with a :) :) :) regexVariable :) :) :).
Solution 24 - Javascript
I wrote a function, for reuse:
function replaceAll(str, from, to) {
let re = new RegExp(`${from}`, "g");
return str.replace(re, to);
}
let str = "my text from here";
let ans = replaceAll( str, "fromValue", "toValue");
ans = replaceAll( ans, "fromValue2", "toValue2");
console.log ( ans );