Thursday, May 31, 2012

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 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

16 comments:

  1. Try sprintf() for JavaScript.



    Update    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.

    ReplyDelete
  2. Building on the previously suggested solutions:

    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}

    ReplyDelete
  3. jsxt, Zippo

    This 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. ;)

    ReplyDelete
  4. I use this simple function:

    String.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.

    ReplyDelete
  5. Number Formatting in JavaScript

    I 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(), ...)

    ReplyDelete
  6. +1 Zippo with exception that the function body needs to be as below or otherwise it appends the current string on every iteration:

    String.prototype.format = function() {
    var formatted = this;
    for (arg in arguments) {
    formatted = formatted.replace("{" + arg + "}", arguments[arg]);
    }
    return formatted;
    };

    ReplyDelete
  7. I'll add my own discoveries which I've found since I asked:


    number_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.

    ReplyDelete
  8. 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.

    ReplyDelete
  9. JavaScript programmers can use String.prototype.sprintf at http://code.google.com/p/jsxt/source/browse/trunk/js/String.js. Below is example:

    var d = new Date();
    var dateStr = '%02d:%02d:%02d'.sprintf(
    d.getHours(),
    d.getMinutes(),
    d.getSeconds());

    ReplyDelete
  10. 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.

    function 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.

    ReplyDelete
  11. 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.

    The Javascript Date class can format localized dates and times.

    ReplyDelete
  12. There are "sprintf" for javascript which you can find it from here:
    http://www.webtoolkit.info/javascript-sprintf.html

    ReplyDelete
  13. 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:

    http://phpjs.org/functions/sprintf

    ReplyDelete
  14. arg function :

    /**
    * 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;
    }

    ReplyDelete
  15. 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.

    ReplyDelete
  16. very elegant

    String.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/

    ReplyDelete