How to manipulate the pattern of a RegExp dynamically?

Joe Ali Source

I have an array of text lines and an array of terms with each term row containing a pair of words. For example, the terms array could be something like:

blue, red
high, low
free, bound
 ...

for each line in the array of lines, I need to go through the list of all terms and replace every occurrence of the first word with the second word; globally and case-insensitive. For example, the line

The sky is Blue and High, very blue and high, yet Free

would become

The sky is red and low, very red and low, yet bound

A code like this:

function filter(lines,terms){
    for (line of lines){
        for (term of terms){
             tofind    = term[0]; //this is a string not RegExp
                                  //still needs the 'gi' flags
             toreplace = term[1];
             line      = line.replace(tofind,toreplace);
        }

    }
}

This is wrong, because tofind needs to be RegExp (pattern, 'gi') and needs to be generated dynamically with each iteration inside the loop.

If the tofind string was static, we could have done:

line = line.replace(/some-static-text-here/gi,toreplace)

I tried line.replace(new RegExp(tofind,'gi'),toreplace) but this throws an error Invalid regular expression: /*Contains/: Nothing to repeat

SO, the question is: How to modify the pattern of the RegExp object dynamically, inside a loop?

javascriptregex

Answers

answered 6 months ago Nina Scholz #1

You could build new regular expression if the terms array does only contains alpha numerical values.

function filter(lines, terms) {
    return lines.map(s => 
        terms.reduce((r, t) => r.replace(new RegExp(t[0], 'gi'), t[1]), s));
}

console.log(filter(['The sky is Blue and High, very blue and high, yet Free'], [['blue', 'red'], ['high', 'low'], ['free', 'bound']]));

comments powered by Disqus