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 posts, and searched my code).
I wanted something that would be like the C# String.Format where you could do something like
string format = String.Format("Hi {0}",name);
just for JavaScript of course and one person gave me a simple answer it was not like a jQuery plugin or anything, but I think you made some JSON thing or something, and it worked and was simple to use.
I for the life of me can't find this post.
I do have this in my code, but I can't seem to find anything that uses it and I am pretty sure I used it a couple of times:
String.prototype.format = function(o)
{
return this.replace(/{([^{}]*)}/g,
function(a, b)
{
var r = o[b];
return typeof r === 'string' ? r : a;
}
);
};
This question is related to
c#
.net
javascript
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'
Here is a useful string formatting function using regular expressions and captures:
function format (fmtstr) {
var args = Array.prototype.slice.call(arguments, 1);
return fmtstr.replace(/\{(\d+)\}/g, function (match, index) {
return args[index];
});
}
Strings can be formatted like C# String.Format:
var str = format('{0}, {1}!', 'Hello', 'world');
console.log(str); // prints "Hello, world!"
the format will place the correct variable in the correct spot, even if they appear out of order:
var str = format('{1}, {0}!', 'Hello', 'world');
console.log(str); // prints "world, Hello!"
Hope this helps!
String.prototype.format = function () {
var formatted = this;
for (var arg in arguments) {
formatted = formatted.split('{' + arg + '}').join(arguments[arg]);
}
return formatted;
};
USAGE:
'Hello {0}!'.format('Word')
->
Hello World!
'He{0}{0}o World!'.format('l')
->
Hello World!
'{0} {1}!'.format('Hello', 'Word')
->
Hello World!
'{0}!'.format('Hello {1}', 'Word')
->
Hello World!
Without a third party function:
string format = "Hi {0}".replace('{0}', name)
With multiple params:
string format = "Hi {0} {1}".replace('{0}', name).replace('{1}', lastname)
//Add "format" method to the string class
//supports: "Welcome {0}. You are the first person named {0}".format("David");
// and "First Name:{} Last name:{}".format("David","Wazy");
// and "Value:{} size:{0} shape:{1} weight:{}".format(value, size, shape, weight)
String.prototype.format = function () {
var content = this;
for (var i = 0; i < arguments.length; i++) {
var target = '{' + i + '}';
content=content.split(target).join(String(arguments[i]))
content = content.replace("{}", String(arguments[i]));
}
return content;
}
alert("I {} this is what {2} want and {} works for {2}!".format("hope","it","you"))
You can mix and match using positional and "named" replacement locations using this function.
Aside from the fact that you are modifying the String prototype, there is nothing wrong with the function you provided. The way you would use it is this way:
"Hello {0},".format(["Bob"]);
If you wanted it as a stand-alone function, you could alter it slightly to this:
function format(string, object) {
return string.replace(/{([^{}]*)}/g,
function(match, group_match)
{
var data = object[group_match];
return typeof data === 'string' ? data : match;
}
);
}
Vittore's method is also good; his function is called with each additional formating option being passed in as an argument, while yours expects an object.
What this actually looks like is John Resig's micro-templating engine.
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
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?`
Your function already takes a JSON object as a parameter:
string format = "Hi {foo}".replace({
"foo": "bar",
"fizz": "buzz"
});
if you notice, the code:
var r = o[b];
looks at your parameter (o) and uses a key-value-pairs within it to resolve the "replace"
Here is what I use. I have this function defined in a utility file:
String.format = function() {
var s = arguments[0];
for (var i = 0; i < arguments.length - 1; i++) {
var reg = new RegExp("\\{" + i + "\\}", "gm");
s = s.replace(reg, arguments[i + 1]);
}
return s;
}
And I call it like so:
var greeting = String.format("Hi, {0}", name);
I do not recall where I found this, but it has been very useful to me. I like it because the syntax is the same as the C# version.
Here is an solution that allows both prototype and function options.
// --------------------------------------------------------------------
// Add prototype for 'String.format' which is c# equivalent
//
// String.format("{0} i{2}a night{1}", "This", "mare", "s ");
// "{0} i{2}a night{1}".format("This", "mare", "s ");
// --------------------------------------------------------------------
if(!String.format)
String.format = function(){
for (var i = 0, args = arguments; i < args.length - 1; i++)
args[0] = args[0].replace("{" + i + "}", args[i + 1]);
return args[0];
};
if(!String.prototype.format && String.format)
String.prototype.format = function(){
var args = Array.prototype.slice.call(arguments).reverse();
args.push(this);
return String.format.apply(this, args.reverse())
};
Enjoy.
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;
};
}
}
})();
String.Format
method from .NET Framework has multiple signatures. The one I like the most uses params keyword in its prototype, i.e.:
public static string Format(
string format,
params Object[] args
)
Using this version, you can not only pass variable number of arguments to it but also an array argument.
Because I like the straightforward solution provided by Jeremy, I'd like to extend it a bit:
var StringHelpers = {
format: function(format, args) {
var i;
if (args instanceof Array) {
for (i = 0; i < args.length; i++) {
format = format.replace(new RegExp('\\{' + i + '\\}', 'gm'), args[i]);
}
return format;
}
for (i = 0; i < arguments.length - 1; i++) {
format = format.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i + 1]);
}
return format;
}
};
Now you can use your JavaScript version of String.Format
in the following manners:
StringHelpers.format("{0}{1}", "a", "b")
and
StringHelpers.format("{0}{1}", ["a", "b"])
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;
}
Just make and use this function:
function format(str, args) {
for (i = 0; i < args.length; i++)
str = str.replace("{" + i + "}", args[i]);
return str;
}
If you don't want to change the str parameter, then before the for
loop, clone (duplicate) it to a new string (make a new copy of str), and set the copy in the for
loop and at last return it instead of the parameter itself.
In C# (Sharp) it is simple create to a copy by just calling String.Clone()
, but I don't know how in JavaScript, but you can search on Google or surf on the Internet and learn ways to do it.
I just gave you my idea about string format in JavaScript.
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"));
I just started porting Java's String.format()
to JavaScript. You might find it useful too.
It supports basic stuff like this:
StringFormat.format("Hi %s, I like %s", ["Rob", "icecream"]);
Which results in
Hi Rob, I like icecream.
But also more advanced numberic formatting and date formatting like:
StringFormat.format("Duke's Birthday: %1$tA %1$te %1$tB, %1$tY", [new Date("2014-12-16")]);
Duke's Birthday: Tuesday 16 December, 2014
See for more in the examples.
Source: Stackoverflow.com