I need to find the most efficient way of matching multiple regular expressions on a single block of text. To give an example of what I need, consider a block of text:
<An improved answer:
var index = {
'Hello': 'Bye',
'World': 'Universe'
};
var pattern = '';
for (var i in index) {
if (pattern != '') pattern += '|';
pattern += i;
}
var text = "Hello World what a beautiful day";
text.replace(new RegExp(pattern, 'g'), function($0) {
return index[$0] != undefined ? index[$0] : $0;
});
Edit
6 years after my original answer (below) I would solve this problem differently
function mreplace (replacements, str) {
let result = str;
for (let [x, y] of replacements)
result = result.replace(x, y);
return result;
}
let input = 'Hello World what a beautiful day';
let output = mreplace ([
[/Hello/, 'Bye'],
[/World/, 'Universe']
], input);
console.log(output);
// "Bye Universe what a beautiful day"
This has as tremendous advantage over the previous answer which required you to write each match twice. It also gives you individual control over each match. For example:
function mreplace (replacements, str) {
let result = str;
for (let [x, y] of replacements)
result = result.replace(x, y);
return result;
}
let input = 'Hello World what a beautiful day';
let output = mreplace ([
//replace static strings
['day', 'night'],
// use regexp and flags where you want them: replace all vowels with nothing
[/[aeiou]/g, ''],
// use captures and callbacks! replace first capital letter with lowercase
[/([A-Z])/, $0 => $0.toLowerCase()]
], input);
console.log(output);
// "hll Wrld wht btfl nght"
Original answer
Andy E's answer can be modified to make adding replacement definitions easier.
var text = "Hello World what a beautiful day";
text.replace(/(Hello|World)/g, function ($0){
var index = {
'Hello': 'Bye',
'World': 'Universe'
};
return index[$0] != undefined ? index[$0] : $0;
});
// "Bye Universe what a beautiful day";
You can pass a function to replace:
var hello = "Hello World what a beautiful day";
hello.replace(/Hello|World/g, function ($0, $1, $2) // $3, $4... $n for captures
{
if ($0 == "Hello")
return "Bye";
else if ($0 == "World")
return "Universe";
});
// Output: "Bye Universe what a beautiful day";
If the question is how to replace multiple generic patterns with corresponding replacements - either strings or functions, it's quite tricky because of special characters, capturing groups and backreference matching.
You can use https://www.npmjs.com/package/union-replacer for this exact purpose. It is basically a string.replace(regexp, string|function)
counterpart, which allows multiple replaces to happen in one pass while preserving full power of string.replace(...)
.
Disclosure: I am the author and the library was developed because we had to support user-configured replaces.