Reputation: 6875
I have a text that has format characters in curly braces.
let str = "My name is {name} and age is {age}!";
I want to change this with an object properties.
var myobj = { name: "x", age: "25" }
The result text should be "My name is x and age is 25!"
I can get the name and age values in text using regex.
let regex = /\{([^}]+)\}/g;
let matches = str.match(regex).map(x => x.replace(/[{}]/g, ""));
matches
is array ["name", "age"]
But how can I replace with object properties using regex? Is possible a short way?
Upvotes: 1
Views: 2606
Reputation: 29096
You can use String#replace
and specify a function as replacement. This will allow you to replace the matched content if it matches a key or skip it;
function replace(text, obj) {
let regex = /\{([^}]+)\}/g;
return text.replace(regex, (fullMatch, capture) => {
//in case no replacement is found, use the initial as default
let result = fullMatch;
//see if we have any replacement for this placeholder
if (capture in obj) {
result = obj[capture];
}
//return the value to be used instead of the placeholder
return result;
})
}
let str = "My name is {name} and age is {age}!";
let myobj = { name: "x", age: "25" };
console.log(replace(str, myobj));
console.log(replace("Hello, {location} is {age} years old", myobj));
Or much shorter if using the nullish coalescing operator (??
). It may not be supported on older environments, so the code might need transpilation for older ones.
function replace(text, obj) {
return text.replace(
/\{([^}]+)\}/g,
(fullMatch, capture) => obj[capture] ?? fullMatch
);
}
let str = "My name is {name} and age is {age}!";
let myobj = { name: "x", age: "25" };
console.log(replace(str, myobj));
console.log(replace("Hello, {location} is {age} years old", myobj));
You can also just skip the regular expression if it's always the same string but the replacements can differ. Using a template literal and destructuring:
function replace({name, age}) {
return `My name is ${name} and age is ${age}!`;
}
let myobj = { name: "x", age: "25" };
console.log(replace(myobj));
Upvotes: 2
Reputation: 627468
You may use .replace
method and get the value from myobj
by key that you already capture into Group 1 with your current regex:
let str = "My name is {name} and age is {age} {x}! {missing from myobj}";
var myobj = { name: "x", age: "25", x: ""}
let regex = /{([^{}]+)}/g;
console.log( str.replace(regex, (x,y) => myobj[y] !== undefined ? myobj[y] : x) );
// or a bit more modern variation
console.log( str.replace(regex, (x,y) => myobj[y] ?? x) );
If the key captured is present (myobj[y] ??
), the corresponding value will be returned. If there is no key found with the regex in myobj
, the whole match will be returned (x
). If you need to return a value without braces if the key is not found, use y
instead of x
here.
There is no need to escape {
or }
in the pattern since they cannot be parsed as a limiting quantifier (in these cases, JavaScript RegExp engine does some "smart" parsing).
Upvotes: 2
Reputation: 382
You can try it String.prototype.replace with a function as parameter.
let str = "My name is {name} and age is {age}!";
var myobj = { name: "x", age: "25" };
let regex = /\{([^}]+)\}/g;
const res = str.replace(regex, (match, key) => myobj[key] || match);
console.log(res);
Upvotes: 1