Can anyone help explain the behavior shown in the code snipit below (from a NodeJS 12 console)? I am trying to replace part of a string with the result from a capture group. This actually works, but when I use that capture group result as the key in an object, instead of the first capture group it's literally using $1.
> tmp
{ LOCALAS: 'world' }
> a
'let the {{{LOCALAS}}} go around'
> a.replace(/\{\{\{(.+)\}\}\}/g, "$1");
'let the LOCALAS go around'
> a.replace(/\{\{\{(.+)\}\}\}/g, tmp["LOCALAS"]);
'let the world go around'
> a.replace(/\{\{\{(.+)\}\}\}/g, tmp["$1"]);
'let the undefined go around'
> tmp["$1"] = "NO";
'NO'
> a.replace(/\{\{\{(.+)\}\}\}/g, tmp["$1"]);
'let the NO go around'
... a friend has provided me an answer that works, but I'd still love to know why the above acts the way it does.
> a.replace(/\{\{\{(.+)\}\}\}/g, function(_,k){return [tmp[k]]});
'let the world go around'
I've been looking for the same thing, and came across this question.
In my case I needed to use the captured value in an eval, not a lookup.
As pointed out by others, we can only use the capture group in plain text substitution.
So this works:
str.replace(/\{\{\{(.+?)\}\}\}/g, '$1')
but this does not work:
str.replace(/\{\{\{(.+?)\}\}\}/g, tmp['$1'])
This is because tmp['$1'] will be evaluated before replace is called.
Since you know the available keys, you can simply iterate over them and do the replacement like so:
let str = 'this is a {{{adj}}} text used as a {{{adj}}} {{{noun}}}';
const tmp = {
'adj' : 'short',
'noun' : 'example',
};
Object.keys(tmp).forEach(key => {
const replaceRegex = new RegExp(`\{\{\{${key}\}\}\}`, 'g');
str = str.replace( replaceRegex, tmp[key] );
});
console.log(str); // prints: "this is a short text used as a short example"
In my case, the values were unknown, so I solved it by extracting the values beforehand and then iterating over them:
let str = 'Mario has {{{"Mario".length}}} letters in his name, and Bowser has {{{"Bowser".length}}}';
const expressions = [];
const captureRegex = /\{\{\{(.*?)\}\}\}/g;
const matches = str.matchAll(captureRegex );
for (const match of matches) expressions.push(match[1]);
expressions.forEach(expression => {
const replaceRegex = new RegExp(`\{\{\{${expression}\}\}\}`, 'g');
str = str.replace( replaceRegex, eval(expression) );
});
console.log(str); // prints: "Mario has 5 letters in his name, and Bowser has 6"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With