1

I have a string with words followed by a colon. I need to replace the colon words in that string with values from an object. I was able to extract out the colon words but not sure on the best way to replace it in the string.

This is what I have:

const string = 'This is :state :buttonName by :name';

const buttonName = 'button link';

const data = {
  state: 'Alabama',
  name: 'Arun'
}

const res = string.match(/:[a-zA-Z]+/g).map(i => i.replace(':', ''))


console.log(res)

// This is Alabama button link by Arun

End result should be

This is Alabama button link by Arun

Please advice.

arunmmanoharan
  • 2,535
  • 2
  • 29
  • 60
  • 1
    Does this answer your question? [How to replace all occurrences of a string in JavaScript](https://stackoverflow.com/questions/1144783/how-to-replace-all-occurrences-of-a-string-in-javascript) – Jeff B Jun 01 '21 at 17:02
  • us regex global flag `replace(/:/g, '')` – ShadowLp174 Jun 01 '21 at 17:06
  • 1
    Certainly it is not a duplicate of [`Can ES6 template literals be substituted at runtime (or reused)?`](https://stackoverflow.com/questions/30003353/can-es6-template-literals-be-substituted-at-runtime-or-reused) as here, the problem is with matching specifically formatted tags (that start with `:` and then only contain letters - not the case in that thread) and replacing them with items from a "dictionary". [How to replace all occurrences of a string in JavaScript](https://stackoverflow.com/questions/1144783/) is not related at all. – Wiktor Stribiżew Jun 02 '21 at 08:27

4 Answers4

5

First of all, you need to move const buttonName = 'button link'; to the array.

You need to use String#replace, but also you need to capture the part of the regex after : and actually use the Group #1 value as key to get the right data value.

Besides, you need to check if the extracted key is inside the dictionary to avoid issues.

You can use

const string = 'This is :state :buttonName by :name';
const data = {
  buttonName: 'button link',
  state: 'Alabama',
  name: 'Arun'
}
const res = string.replace(/:([a-zA-Z]+)/g, (m, i) => i in data ? data[i] : m)
console.log(res)
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
3

You can split the string and then call array map to replace words and the join to final string

const str= 'This is :state :buttonName by :name';

str.split(' ').map(a => {
                         if(a.startsWith(":"))
                           return data[a.replace(":","")]; 
   
                         return a;
                  }).join(' ');
Vivek Bani
  • 3,703
  • 1
  • 9
  • 18
1

If you've already stripped the ":" from the string you can just iterate your object keys and replace them with the respective values.

...
const res = string.match(/:[a-zA-Z]+/g).map(i => i.replace(':', ''))

for (const [key, value] of Object.entries(data)) {
    res = res.replaceAll(key, value);
}
Viktor
  • 151
  • 1
  • 2
1

Wiktor's answer is good. But if it needs to replace the global variable as well, we can write the code as belows.

const res = string.replace(/:([a-zA-Z_]+)/g, (m, i) => data[i] ?? eval(i) ?? m);
console.log(res)

This code didn't do exception handling yet. It should be in consideration. So we can define a replacer function handling exception

const replacer = (m, i) => {
    try {
        return data[i] ?? eval(i);
    } catch {
        return m;
    }
}

const res = string.replace(/:([a-zA-Z_]+)/g, replacer);
TopW3
  • 1,477
  • 1
  • 8
  • 14