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 thousand separator format for numbers for now, but something that handles lots of combinations (including dates) would be good.
I realise Microsoft's Ajax library provides a version of String.Format()
but we don't want the entire overhead of that framework.
Source: Tips4all
Try sprintf() for JavaScript.
ReplyDeleteUpdate Ok, if you really want to do a simply 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:
ReplyDeleteString.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}
jsxt, Zippo
ReplyDeleteThis option fits better.
String.prototype.format = function() {
var formatted = this;
for (var i = 0; i < arguments.length; i++) {
var regexp = new RegExp('\\{'+i+'\\}', 'gi');
formatted = formatted.replace(regexp, arguments[i]);
}
return formatted;
};
With this option I can replace string like thise:
'The {0} is dead. Don\'t code {0}. Code {1} that is open source!'.format('ASP', 'PHP');
With your code the second {0} wouldn't be replaced. ;)
I use this simple function:
ReplyDeleteString.prototype.format = function() {
var formatted = this;
for(arg in arguments) {
formatted = formatted.replace("{" + arg + "}", arguments[arg]);
}
return formatted;
};
That's very similar to string.format:
"{0} is dead, but {1} is alive!".format("ASP", "ASP.NET")
Update after 4 months: Code fixed thanks to user437231!
Update: Fixed this up. it used to put this.replace into formatted, thus replacing it everytime and so the format would only work for the last argument.
Number Formatting in JavaScript
ReplyDeleteI got to this question page hoping to find how to format numbers in JavaScript, without introducing yet another library. Here's what I've found:
Rounding floating-point numbers
The equivalent of sprintf("%.2f", num) in JavaScript seems to be num.toFixed(2), which rounds num to 2 decimal places, with rounding.
12.345.toFixed(2); // returns "12.35" (rounding!)
12.3.toFixed(2); // returns "12.30" (zero padding)
Exponential form
The equivalent of sprintf("%.2e", num) is num.toExponential(2).
22222 .toExponential(1); // "2.2e+4"
// ^ Note the space, which keeps the . from being a decimal point
Hexadecimal and other bases
To print numbers in base B, try num.toString(B). JavaScript supports automatic conversion to bases 2 through 36.
3735928559 .toString(16); // "deadbeef"
parseInt("deadbeef", 16); // 3735928559
Reference Pages
Quick tutorial on JS number formatting
Mozilla reference page for toFixed() (with links to toPrecision(), toExponential(), toLocaleString(), ...)
+1 Zippo with exception that the function body needs to be as below or otherwise it appends the current string on every iteration:
ReplyDeleteString.prototype.format = function() {
var formatted = this;
for (arg in arguments) {
formatted = formatted.replace("{" + arg + "}", arguments[arg]);
}
return formatted;
};
I'll add my own discoveries which I've found since I asked:
ReplyDeletenumber_format (for thousand seperator/currency formatting)
sprintf (same author as above)
Sadly it seems sprintf doesn't handle thousand seperator formatting like .NET's string format.
I use a small library called String.format for JavaScript which supports most of the format string capabilities (including format of numbers and dates), and uses the .NET syntax. The script itself is smaller than 4 kB, so it doesn't create much of overhead.
ReplyDeleteJavaScript programmers can use String.prototype.sprintf at http://code.google.com/p/jsxt/source/browse/trunk/js/String.js. Below is example:
ReplyDeletevar d = new Date();
var dateStr = '%02d:%02d:%02d'.sprintf(
d.getHours(),
d.getMinutes(),
d.getSeconds());
Here's a minimal implementation of sprintf in Javascript: it only does "%s". Useless to the OP, but other people who stumble across this thread coming from Google might benefit from it.
ReplyDeletefunction sprintf(format, etc) {
var arg = arguments;
var i = 1;
return format.replace(/%((%)|s)/g, function (m) { return m[2] || arg[i++] })
}
Example:
alert(sprintf('Latitude: %s, Longitude: %s', 41.847, -87.661));
In contrast with similar solutions in previous replies, this one does all substitutions in one go, so it will not replace parts of previously replaced values.
If you are looking to handle the thousands separator, you should really use toLocaleString() from the Javascript Number class since it will format the string for the user's region.
ReplyDeleteThe Javascript Date class can format localized dates and times.
There are "sprintf" for javascript which you can find it from here:
ReplyDeletehttp://www.webtoolkit.info/javascript-sprintf.html
The PHPJS project has written Javascript implementations for many of PHP's functions. Since PHP's sprintf() function is basically the same as C's printf(), their JS implementation of it should satisfy your needs:
ReplyDeletehttp://phpjs.org/functions/sprintf
arg function :
ReplyDelete/**
* Qt stil arg()
* var scr = "<div id='%1' class='%2'></div>".arg("mydiv").arg("mydivClass");
*/
String.prototype.arg = function() {
var signIndex = this.indexOf("%");
var result = this;
if (signIndex > -1 && arguments.length > 0) {
var argNumber = this.charAt(signIndex + 1);
var _arg = "%"+argNumber;
var argCount = this.split(_arg);
for (var itemIndex = 0; itemIndex < argCount.length; itemIndex++) {
result = result.replace(_arg, arguments[0]);
}
}
return result;
}
There is also Globalize.format in the jQuery Globalize project, the official globalization service for jQuery UI. IT's nice when you need culture-aware formatting.
ReplyDeletevery elegant
ReplyDeleteString.prototype.format = function (){
var args = arguments;
return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (curlyBrack, index) {
return ((curlyBrack == "{{") ? "{" : ((curlyBrack == "}}") ? "}" : args[index]));
});
};
"{0}{1}".format("{1}", "{0}")
cerdit goes to http://technoblogia.net/2011/11/08/%D7%98%D7%99%D7%A4-%D7%A4%D7%95%D7%A0%D7%A7%D7%A6%D7%99%D7%99%D7%AA-%D7%A2%D7%96%D7%A8-%D7%91-javascript-%D7%9C%D7%A2%D7%99%D7%A6%D7%95%D7%91-%D7%9E%D7%97%D7%A8%D7%95%D7%96%D7%95%D7%AA/