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

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

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


当前回答

一个稍有不同的版本,我更喜欢的版本(这个版本使用{xxx}标记,而不是{0}编号的参数,这更易于自我记录,更适合本地化):

String.prototype.format = function(tokens) {
  var formatted = this;
  for (var token in tokens)
    if (tokens.hasOwnProperty(token))
      formatted = formatted.replace(RegExp("{" + token + "}", "g"), tokens[token]);
  return formatted;
};

一种变化是:

  var formatted = l(this);

它首先调用l()本地化函数。

其他回答

我想分享我对“问题”的解决方案。我没有重新发明轮子,但试图根据JavaScript已经做的事情找到解决方案。优点是,您可以免费获得所有隐式转换。设置字符串的原型属性$提供了一个非常好和紧凑的语法(参见下面的示例)。这可能不是最有效的方法,但在大多数情况下,处理输出时不必进行超级优化。

String.form = function(str, arr) {
    var i = -1;
    function callback(exp, p0, p1, p2, p3, p4) {
        if (exp=='%%') return '%';
        if (arr[++i]===undefined) return undefined;
        exp  = p2 ? parseInt(p2.substr(1)) : undefined;
        var base = p3 ? parseInt(p3.substr(1)) : undefined;
        var val;
        switch (p4) {
            case 's': val = arr[i]; break;
            case 'c': val = arr[i][0]; break;
            case 'f': val = parseFloat(arr[i]).toFixed(exp); break;
            case 'p': val = parseFloat(arr[i]).toPrecision(exp); break;
            case 'e': val = parseFloat(arr[i]).toExponential(exp); break;
            case 'x': val = parseInt(arr[i]).toString(base?base:16); break;
            case 'd': val = parseFloat(parseInt(arr[i], base?base:10).toPrecision(exp)).toFixed(0); break;
        }
        val = typeof(val)=='object' ? JSON.stringify(val) : val.toString(base);
        var sz = parseInt(p1); /* padding size */
        var ch = p1 && p1[0]=='0' ? '0' : ' '; /* isnull? */
        while (val.length<sz) val = p0 !== undefined ? val+ch : ch+val; /* isminus? */
       return val;
    }
    var regex = /%(-)?(0?[0-9]+)?([.][0-9]+)?([#][0-9]+)?([scfpexd%])/g;
    return str.replace(regex, callback);
}

String.prototype.$ = function() {
    return String.form(this, Array.prototype.slice.call(arguments));
}

以下是几个示例:

String.format("%s %s", [ "This is a string", 11 ])
console.log("%s %s".$("This is a string", 11))
var arr = [ "12.3", 13.6 ]; console.log("Array: %s".$(arr));
var obj = { test:"test", id:12 }; console.log("Object: %s".$(obj));
console.log("%c", "Test");
console.log("%5d".$(12)); // '   12'
console.log("%05d".$(12)); // '00012'
console.log("%-5d".$(12)); // '12   '
console.log("%5.2d".$(123)); // '  120'
console.log("%5.2f".$(1.1)); // ' 1.10'
console.log("%10.2e".$(1.1)); // '   1.10e+0'
console.log("%5.3p".$(1.12345)); // ' 1.12'
console.log("%5x".$(45054)); // ' affe'
console.log("%20#2x".$("45054")); // '    1010111111111110'
console.log("%6#2d".$("111")); // '     7'
console.log("%6#16d".$("affe")); // ' 45054'

jQueryGlobalize项目中还有Globalize.format,这是jQueryUI的官方全球化服务。当您需要具有文化意识的格式时,这很好。

我用这个:

String.prototype.format = function() {
    var newStr = this, i = 0;
    while (/%s/.test(newStr))
        newStr = newStr.replace("%s", arguments[i++])

    return newStr;
}

然后我称之为:

"<h1>%s</h1><p>%s</p>".format("Header", "Just a test!");

JavaScript有“sprintf”,您可以在http://www.webtoolkit.info/javascript-sprintf.html.

JavaScript中的sprintf()函数模拟为Vue过滤器和String.protype.format()扩展:

/**
 * Returns a formatted string.
 *
 * @param template
 * @param values
 * @return string
 */
String.format = function (template, ...values) {
    let i = -1;

    function callback(exp, p0, p1, p2, p3, p4) {
        if (exp === '%%') return '%';
        if (values[++i] === undefined) return undefined;

        exp = p2 ? parseInt(p2.substr(1)) : undefined;

        let base = p3 ? parseInt(p3.substr(1)) : undefined;
        let val;

        switch (p4) {
            case 's': val = values[i]; break;
            case 'c': val = values[i][0]; break;
            case 'f': val = parseFloat(values[i]).toFixed(exp); break;
            case 'p': val = parseFloat(values[i]).toPrecision(exp); break;
            case 'e': val = parseFloat(values[i]).toExponential(exp); break;
            case 'x': val = parseInt(values[i]).toString(base ? base : 16); break;
            case 'd': val = parseFloat(parseInt(values[i], base ? base : 10).toPrecision(exp)).toFixed(0); break;
        }
        val = typeof (val) == 'object' ? JSON.stringify(val) : val.toString(base);
        let sz = parseInt(p1); /* padding size */
        let ch = p1 && p1[0] === '0' ? '0' : ' '; /* isnull? */

        while (val.length < sz) val = p0 !== undefined ? val + ch : ch + val; /* isminus? */

        return val;
    }

    let regex = /%(-)?(0?[0-9]+)?([.][0-9]+)?([#][0-9]+)?([scfpexd%])/g;

    return template.replace(regex, callback);
}

String.prototype.format = function() {
    return String.format(this, ...arguments);
}

const StringFormat = {
    install: (Vue, options) => {
        Vue.filter('format', function () {
            return String.format(...arguments);
        });
    },
};

export default StringFormat;

原始答案:JavaScript相当于printf/String.Format