Use dynamic (variable) string as regex pattern in JavaScript

I want to add a (variable) tag to values with regex, the pattern works fine with PHP but I have troubles implementing it into JavaScript.

The pattern is (value is the variable):

/(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/is

I escaped the backslashes:

var str = $("#div").html();
var regex = "/(?!(?:[^<]+>|[^>]+<\\/a>))\\b(" + value + ")\\b/is";
$("#div").html(str.replace(regex, "<a href='#" + value +">" + value + "</a>"));

But this seem not to be right, I logged the pattern and its exactly what it should be. Any ideas?

Answers:

Answer

To create the regex from a string, you have to use JavaScript's RegExp object.

If you also want to match/replace more than one time, then you must add the g (global match) flag. Here's an example:

var stringToGoIntoTheRegex = "abc";
var regex = new RegExp("#" + stringToGoIntoTheRegex + "#", "g");
// at this point, the line above is the same as: var regex = /#abc#/g;

var input = "Hello this is #abc# some #abc# stuff.";
var output = input.replace(regex, "!!");
alert(output); // Hello this is !! some !! stuff.

JSFiddle demo here.


In the general case, escape the string before using as regex:

Not every string is a valid regex, though: there are some speciall characters, like ( or [. To work around this issue, simply escape the string before turning it into a regex. A utility function for that goes in the sample below:

function escapeRegExp(stringToGoIntoTheRegex) {
    return stringToGoIntoTheRegex.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}

var stringToGoIntoTheRegex = escapeRegExp("abc"); // this is the only change from above
var regex = new RegExp("#" + stringToGoIntoTheRegex + "#", "g");
// at this point, the line above is the same as: var regex = /#abc#/g;

var input = "Hello this is #abc# some #abc# stuff.";
var output = input.replace(regex, "!!");
alert(output); // Hello this is !! some !! stuff.

JSFiddle demo here.



Note: the regex in the question uses the s modifier, which didn't exist at the time of the question, but does exist -- a s (dotall) flag/modifier in JavaScript -- today.

Answer

I found this thread useful - so I thought I would add the answer to my own problem.

I wanted to edit a database configuration file (datastax cassandra) from a node application in javascript and for one of the settings in the file I needed to match on a string and then replace the line following it.

This was my solution.

dse_cassandra_yaml='/etc/dse/cassandra/cassandra.yaml'

// a) find the searchString and grab all text on the following line to it
// b) replace all next line text with a newString supplied to function
// note - leaves searchString text untouched
function replaceStringNextLine(file, searchString, newString) {
fs.readFile(file, 'utf-8', function(err, data){
if (err) throw err;
    // need to use double escape '\\' when putting regex in strings !
    var re = "\\s+(\\-\\s(.*)?)(?:\\s|$)";
    var myRegExp = new RegExp(searchString + re, "g");
    var match = myRegExp.exec(data);
    var replaceThis = match[1];
    var writeString = data.replace(replaceThis, newString);
    fs.writeFile(file, writeString, 'utf-8', function (err) {
    if (err) throw err;
        console.log(file + ' updated');
    });
});
}

searchString = "data_file_directories:"
newString = "- /mnt/cassandra/data"

replaceStringNextLine(dse_cassandra_yaml, searchString, newString );

After running, it will change the existing data directory setting to the new one:

config file before:

data_file_directories:  
   - /var/lib/cassandra/data

config file after:

data_file_directories:  
- /mnt/cassandra/data
Answer

If you are trying to use a variable value in the expression, you must use the RegExp "constructor".

var regex="(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b";
new RegExp(regex, "is")
Answer

You don't need the " to define a regular expression so just:

var regex = /(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/is; // this is valid syntax

If value is a variable and you want a dynamic regular expression then you can't use this notation; use the alternative notation.

String.replace also accepts strings as input, so you can do "fox".replace("fox", "bear");

Alternative:

var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/", "is");
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b/", "is");
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(.*?)\b/", "is");

Keep in mind that if value contains regular expressions characters like (, [ and ? you will need to escape them.

Answer

I found I had to double slash the \b to get it working. For example to remove "1x" words from a string using a variable, I needed to use:

    str = "1x";
    var regex = new RegExp("\\b"+str+"\\b","g"); // same as inv.replace(/\b1x\b/g, "")
    inv=inv.replace(regex, "");
Answer
var string = "Hi welcome to stack overflow"
var toSearch = "stack"

//case insensitive search

var result = string.search(new RegExp(toSearch, "i")) > 0 ? 'Matched' : 'notMatched'

https://jsfiddle.net/9f0mb6Lz/

Hope this helps

Answer

Much easier way: use template literals.

var variable = 'foo'
var expression = `.*${variable}.*`
var re = new RegExp(expression, 'g')
re.test('fdjklsffoodjkslfd') // true
re.test('fdjklsfdjkslfd') // false

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.