konsalex
konsalex

Reputation: 469

Replace multiple strings containing $ sign

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

Answers (3)

Limbo
Limbo

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.

  1. Function that is passed as argument accepts one or more arguments: first is a full match and the others are captured groups. It should return the string, that should replace the full match.
  2. In our regular expression we described that we want to match all possible substrings in format \$\(([^)]+)\), 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

Code Maniac
Code Maniac

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

David Lemon
David Lemon

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

Related Questions