JavaScript equivalent to printf/string.format
I'm looking for a good JavaScript equivalent of the C/PHP printf()
or for C#/Java programmers, String.Format()
( IFormatProvider
for .NET).
My basic requirement is a thousand separator format for numbers for now, but something that handles lots of combinations (including dates) would be good.
I realize Microsoft's Ajax library provides a version of String.Format()
, but we don't want the entire overhead of that framework.
Try sprintf() for JavaScript.
Update Ok, if you really want to do a simple format method on your own, don't do the replacements successively but do them simultaneously.
Because most of the other proposals that are mentioned fail when a replace string of previous replacement does also contain a format sequence like this:
"{0}{1}".format("{1}", "{0}")
Normally you would expect the output to be {1}{0}
but the actual output is {1}{1}
. So do a simultaneously replacement instead like in fearphage's suggestion.
Building on the previously suggested solutions:
// First, checks if it isn't implemented yet.
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
;
});
};
}
"{0} is dead, but {1} is alive! {0} {2}".format("ASP", "ASP.NET")
outputs
ASP is dead, but ASP.NET is alive! ASP {2}
If you prefer not to modify String
's prototype:
if (!String.format) {
String.format = function(format) {
var args = Array.prototype.slice.call(arguments, 1);
return format.replace(/{(d+)}/g, function(match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
}
Gives you the much more familiar:
String.format('{0} is dead, but {1} is alive! {0} {2}', 'ASP', 'ASP.NET');
with the same result:
ASP is dead, but ASP.NET is alive! ASP {2}
It's funny because Stack Overflow actually has their own formatting function for the String
prototype called formatUnicorn
. Try it! Go into the console and type something like:
"Hello, {name}, are you feeling {adjective}?".formatUnicorn({name:"Gabriel", adjective: "OK"});
You get this output:
Hello, Gabriel, are you feeling OK?
You can use objects, arrays, and strings as arguments! I got its code and reworked it to produce a new version of String.prototype.format
:
String.prototype.formatUnicorn = String.prototype.formatUnicorn ||
function () {
"use strict";
var str = this.toString();
if (arguments.length) {
var t = typeof arguments[0];
var key;
var args = ("string" === t || "number" === t) ?
Array.prototype.slice.call(arguments)
: arguments[0];
for (key in args) {
str = str.replace(new RegExp("{" + key + "}", "gi"), args[key]);
}
}
return str;
};
Note the clever Array.prototype.slice.call(arguments)
call -- that means if you throw in arguments that are strings or numbers, not a single JSON-style object, you get C#'s String.Format
behavior almost exactly.
"a{0}bcd{1}ef".formatUnicorn("foo", "bar"); // yields "aFOObcdBARef"
That's because Array
's slice
will force whatever's in arguments
into an Array
, whether it was originally or not, and the key
will be the index (0, 1, 2...) of each array element coerced into a string (eg, "0", so "{0}"
for your first regexp pattern).
Neat.
链接地址: http://www.djcxy.com/p/3918.html