Reputation: 469
I face a problem with regex and string replace and I would love a little bit of help.
I have a string with the following format
<div class="$(unique-result) single-result data-index=$(i)"><div class="airport-data data-index=$(i)">$(name)<br>$(city) ,$(country)</div><div class="airport-code data-index=$(i)">$(IATA)</div></div>
and I need to replace all the $(unique-result) with a string of mine.
I tried the following code but I can't seem to find out why this doesn't work
string.replace(new RegExp('\\$(unique-result)', 'g'), changeString)
The result is the exact same string I gave as an input.
Could anyone help me out but also point out why it didn't work?
Thank you in advance.
Upvotes: 1
Views: 91
Reputation: 2290
There is more general solution.
First of all, as I mentioned in comments, you don't need to use the RegExp
constructor, you can simply pass your regexp between slashes and use flags after last slash:
str.replace(/\$\(unique-result\)/g, "someValue")
The second moment is that String.prototype.replace
can accept a function as a second parameter. This will be helpful when there is a lot of named templates in you string. For example, you have the next incoming string:
var incomingString = "$(first-value) says $(second-value) when there is $(third-value)"
With code that you've provided you should call replace
3 times. But if you will use a function as a second parameter, this can be simplified to:
var incomingString = "$(first-value) says $(second-value) when there is $(third-value)"
var data = {
"first-value": "Kappa",
"second-value": "Hey!",
"third-value": "GreyFaceNoSpace"
}
var resultString = incomingString.replace(/\$\(([^)]+)\)/g, (match, capture) => {
console.log(match, capture)
return data[capture]
})
console.log(resultString)
"WHAT IS GOING ON HERE?!" you will probably ask. Nothing complex.
\$\(([^)]+)\)
, where [^)]+
refers to one-or-more-of-any-symbols-except-a-closing-bracket, and this construction should be captured (it is between not-sanitized brackets).So, once this regexp will match, it will pass the whole $(...)
construction into match
argument of passed function, and the name of the template into capture
argument. So capture
is our key for some data storage and we just returning this value in the function.
That's it! Hope, this will be helpful :)
Upvotes: 2
Reputation: 37755
You missed escaping. you need to escape properly
let str = `<div class="$(unique-result) single-result data-index=$(i)"><div class="airport-data data-index=$(i)">$(name)<br>$(city) ,$(country)</div><div class="airport-code data-index=$(i)">$(IATA)</div></div>`
let op = str.replace(new RegExp('\\$\\(unique-result\\)','g'), 'Changed')
console.log(op)
In case i am not using any variable i prefer using regex literal (//)
let str = `<div class="$(unique-result) single-result data-index=$(i)"><div class="airport-data data-index=$(i)">$(name)<br>$(city) ,$(country)</div><div class="airport-code data-index=$(i)">$(IATA)</div></div>`
let op = str.replace(/\$\(unique-result\)/g, 'Changed')
console.log(op)
Upvotes: 2
Reputation: 1560
You can use a simple function to make the substitution. Match every $(string)
and apply a function to replace it with a variable stored in an object. Easy and extensible.
const tpl = '<div class="$(unique-result) single-result data-index=$(i)"><div class="airport-data data-index=$(i)">$(name)<br>$(city) ,$(country)</div><div class="airport-code data-index=$(i)">$(IATA)</div></div>';
const vars = {
i : 9,
'unique-result' : 'uniq',
country : 'gb',
city : 'Manchester',
IATA : 'MCH'
};
const replaceVars = (tpl,vars) => {
const replacer = (m, m1) =>
typeof vars[m1] != 'undefined' ? vars[m1] : '';
return tpl.replace(/\$\(([\w-]+)\)/g, replacer);
};
console.log(replaceVars(tpl,vars));
Upvotes: 0