我正在寻找一个与C/PHP printf()或C#/Java程序员String.Format()(IFormatProvider for.NET)相当的JavaScript。

目前,我的基本要求是数字的千位分隔符格式,但处理大量组合(包括日期)的格式会很好。

我意识到Microsoft的Ajax库提供了String.Format()的一个版本,但我们不希望该框架的全部开销。


当前回答

+1 Zippo,但函数体需要如下所示,否则它会在每次迭代时附加当前字符串:

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

其他回答

我有一个非常接近Peter的解决方案,但它涉及数字和对象情况。

if (!String.prototype.format) {
  String.prototype.format = function() {
    var args;
    args = arguments;
    if (args.length === 1 && args[0] !== null && typeof args[0] === 'object') {
      args = args[0];
    }
    return this.replace(/{([^}]*)}/g, function(match, key) {
      return (typeof args[key] !== "undefined" ? args[key] : match);
    });
  };
}

也许处理所有深度案件会更好,但对于我的需要来说,这很好。

"This is an example from {name}".format({name:"Blaine"});
"This is an example from {0}".format("Blaine");

PS:如果你在AngularJS这样的模板框架中使用翻译,这个函数非常酷:

<h1> {{('hello-message'|translate).format(user)}} <h1>
<h1> {{('hello-by-name'|translate).format( user ? user.name : 'You' )}} <h1>

en.json是什么样子的

{
    "hello-message": "Hello {name}, welcome.",
    "hello-by-name": "Hello {0}, welcome."
}

您可以使用此功能

            String.prototype.format = function (args) {
            var str = this;
            return str.replace(String.prototype.format.regex, function(item) {
                var intVal = parseInt(item.substring(1, item.length - 1));
                var replace;
                if (intVal >= 0) {
                    replace = args[intVal];
                } else if (intVal === -1) {
                    replace = "{";
                } else if (intVal === -2) {
                    replace = "}";
                } else {
                    replace = "";
                }
                return replace;
            });
        };
        String.prototype.format.regex = new RegExp("{-?[0-9]+}", "g");

        // Sample usage.
        var str = "She {1} {0}{2} by the {0}{3}. {-1}^_^{-2}";
        str = str.format(["sea", "sells", "shells", "shore"]);
        alert(str);

对于Node.js用户,util.format具有类似printf的功能:

util.format("%s world", "Hello")

使用Lodash,您可以获得模板功能:

使用ES模板文本分隔符作为“插入”分隔符。通过替换“interpole”分隔符禁用支持。

var compiled = _.template('hello ${ user }!');
compiled({ 'user': 'pebbles' });
// => 'hello pebbles!

基于先前建议的解决方案:

// 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}已死亡,但{1}仍活着!{0{{2}”.format(“ASP”,“ASP.NET”)

输出

ASP死了,但ASP.NET活了!ASP{2}


如果您不想修改String的原型:

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
      ;
    });
  };
}

让您更加熟悉:

String.format(“{0}无效,但{1}有效!{0{{2}”,“ASP”,“ASP.NET”);

结果相同:

ASP死了,但ASP.NET活了!ASP{2}