协慌网

登录 贡献 社区

JavaScript 等效于 printf / String.Format

我正在寻找一个很好的 JavaScript 等价的 C / PHP printf()或 C#/ Java 程序员, String.Format()IFormatProvider for .NET)。

我的基本要求是现在有数千个数字分隔符格式,但处理许多组合(包括日期)的东西会很好。

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

答案

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

// 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")

输出

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} is dead, but {1} is alive! {0} {2}', 'ASP', 'ASP.NET');

结果相同:

ASP 已经死了,但 ASP.NET 还活着! ASP {2}

编辑:从 ES6 开始,您可以使用模板字符串:

let soMany = 10;
console.log(`This is ${soMany} times easier!`);
// "This is 10 times easier!

有关详细信息,请参阅 Kim 的答案

原始答案:

试试用于 JavaScript 的 sprintf()


更新确定,如果您真的想自己做一个简单的格式化方法,请不要连续进行替换,而是同时进行。

因为当前替换的替换字符串也包含如下格式序列时,提及的大多数其他提议都会失败:

"{0}{1}".format("{1}", "{0}")

通常,您希望输出为{1}{0}但实际输出为{1}{1} 。所以同时替换就像在恐惧症的建议中一样

这很有趣,因为 Stack Overflow 实际上有一个名为formatUnicornString原型的格式化函数。尝试一下!进入控制台并键入以下内容:

"Hello, {name}, are you feeling {adjective}?".formatUnicorn({name:"Gabriel", adjective: "OK"});

萤火

你得到这个输出:

Hello, Gabriel, are you feeling OK?

您可以使用对象,数组和字符串作为参数!我得到了它的代码并重新编写它以生成一个新版本的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;
};

注意聪明的Array.prototype.slice.call(arguments)调用 - 这意味着如果你抛出的是字符串或数字的参数,而不是单个 JSON 样式的对象,你几乎可以得到 C#的String.Format行为。

"a{0}bcd{1}ef".formatUnicorn("foo", "bar"); // yields "aFOObcdBARef"

这是因为Arrayslice会强制arguments任何内容进入Array ,无论它是否是最初的,并且key将是每个数组元素强制转换为字符串的索引(0,1,2 ...)(例如, “0”,所以"\\{0\\}"为您的第一个正则表达式模式)。

整齐。