Replacing Text Inside of Curley Braces JavaScript
First, String.replace
is not destructive - it doesn't change the string itself, so you'll have to set myString = myString.replace(...)
. Second, you can create RegExp
objects dynamically with new RegExp
, so the result of all that would be:
var myString = "This is {name}'s {adjective} {type} in JavaScript! Yes, a {type}!", replaceArray = ['name', 'adjective', 'type'], replaceWith = ['John', 'simple', 'string'];for(var i = 0; i < replaceArray.length; i++) { myString = myString.replace(new RegExp('{' + replaceArray[i] + '}', 'gi'), replaceWith[i]);}
Strings are immutable
Strings in JavaScript are immutable. It means that this will never work as you expect:
myString.replace(x, y);alert(myString);
This is not just a problem with .replace()
- nothing can mutate a string in JavaScript. What you can do instead is:
myString = myString.replace(x, y);alert(myString);
Regex literals don't interpolate values
Regular expression literals in JavaScript don't interpolate values so this will still not work:
myString = myString.replace(/\{replaceArray[i]\}/gi, replaceWith[i]);
You have to do something like this instead:
myString = myString.replace(new RegExp('\{'+replaceArray[i]+'\}', 'gi'), replaceWith[i]);
But this is a little bit messy, so you may create a list of regexes first:
var regexes = replaceArray.map(function (string) { return new RegExp('\{' + string + '\}', 'gi');});for(var i = 0; i < replaceArray.length; i ++) { myString = myString.replace(regexes[i], replaceWith[i]);}
As you can see, you can also use i < replaceArray.length
instead of i <= replaceArray.length - 1
to simplify your loop condition.
Update 2017
Now you can make it even simpler:
var regexes = replaceArray.map(string => new RegExp(`\{${string}\}`, 'gi'));for(var i = 0; i < replaceArray.length; i ++) { myString = myString.replace(regexes[i], replaceWith[i]);}
Without a loop
Instead of looping and applying .replace()
function over and over again, you can do it only once like this:
var mapping = {};replaceArray.forEach((e,i) => mapping[`{${e}}`] = replaceWith[i]);myString = myString.replace(/\{\w+\}/ig, n => mapping[n]);
See DEMO.
Templating engines
You are basically creating your own templating engine. If you want to use a ready solution instead, then consider using:
or something like that.
An example of what you are trying to do using Mustache would be:
var myString = "This is {{name}}'s {{adjective}} {{type}} in JavaScript! Yes, a {{type}}!";var myData = {name: 'John', adjective: 'simple', type: 'string'};myString = Mustache.to_html(myString, myData);alert(myString);
See DEMO.
The best way I have found to do this, is to use an in-line replace function like others have mentioned, and from whom I borrowed. Special shout out to @yannic-hamann for the regex and clear example. I am not worried about performance, as I am only doing this to construct paths.
I found my solution in MDN's docs.
const interpolateUrl = (string, values) => string.replace(/{(.*?)}/g, (match, offset) => values[offset]);const path = 'theresalways/{what}/inthe/{fruit}-stand/{who}';const paths = { what: 'money', fruit: 'banana', who: 'michael',};const expected = 'theresalways/money/inthe/banana-stand/michael';const url = interpolateUrl(path, paths);console.log(`Is Equal: ${expected === url}`);console.log(`URL: ${url}`)