arunmmanoharan
arunmmanoharan

Reputation: 2675

Replace certain values in a string based on a mapping - JS

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.

Upvotes: 2

Views: 1802

Answers (4)

TopW3
TopW3

Reputation: 1527

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);

Upvotes: 1

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627190

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)

Upvotes: 7

Viktor
Viktor

Reputation: 161

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);
}

Upvotes: 1

Rajdeep D
Rajdeep D

Reputation: 3920

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(' ');

Upvotes: 3

Related Questions