This is driving me nuts. I believe I asked this exact same question, but I can\'t find it any more (I used Stack Overflow search, Google Search, manually searched my po
Use a template literal in ECMAScript 6:
var customer = { name: "Foo" }
var card = { amount: 7, product: "Bar", unitprice: 42 }
var message = `Hello ${customer.name},
want to buy ${card.amount} ${card.product} for
a total of ${card.amount * card.unitprice} bucks?`
Here's a solution that just works with String.prototype:
String.prototype.format = function() {
var s = this;
for (var i = 0; i < arguments.length; i++) {
var reg = new RegExp("\\{" + i + "\\}", "gm");
s = s.replace(reg, arguments[i]);
}
return s;
}
Here are my two cents:
function stringFormat(str) {
if (str !== undefined && str !== null) {
str = String(str);
if (str.trim() !== "") {
var args = arguments;
return str.replace(/(\{[^}]+\})/g, function(match) {
var n = +match.slice(1, -1);
if (n >= 0 && n < args.length - 1) {
var a = args[n + 1];
return (a !== undefined && a !== null) ? String(a) : "";
}
return match;
});
}
}
return "";
}
alert(stringFormat("{1}, {0}. You're looking {2} today.",
"Dave", "Hello", Math.random() > 0.5 ? "well" : "good"));
Based on @roydukkey's answer, a bit more optimized for runtime (it caches the regexes):
(function () {
if (!String.prototype.format) {
var regexes = {};
String.prototype.format = function (parameters) {
for (var formatMessage = this, args = arguments, i = args.length; --i >= 0;)
formatMessage = formatMessage.replace(regexes[i] || (regexes[i] = RegExp("\\{" + (i) + "\\}", "gm")), args[i]);
return formatMessage;
};
if (!String.format) {
String.format = function (formatMessage, params) {
for (var args = arguments, i = args.length; --i;)
formatMessage = formatMessage.replace(regexes[i - 1] || (regexes[i - 1] = RegExp("\\{" + (i - 1) + "\\}", "gm")), args[i]);
return formatMessage;
};
}
}
})();
if (!String.prototype.format) {
String.prototype.format = function () {
var args = arguments;
return this.replace(/{(\d+)}/g, function (match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
}
Usage:
'{0}-{1}'.format('a','b');
// Result: 'a-b'
JSFiddle
You can do series of replaces like that:
function format(str)
{
for(i = 1; i < arguments.length; i++)
{
str = str.replace('{' + (i - 1) + '}', arguments[i]);
}
return str;
}
Better approach will be to use replace with function parameter:
function format(str, obj) {
return str.replace(/\{\s*([^}\s]+)\s*\}/g, function(m, p1, offset, string) {
return obj[p1]
})
}
This way you can provide both indices and named parameters:
var arr = ['0000', '1111', '2222']
arr.a = 'aaaa'
str = format(" { 0 } , {1}, { 2}, {a}", arr)
// returns 0000 , 1111, 2222, aaaa