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

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

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


当前回答

好的,首先我们将设置一些要使用的变量:

    const date = new Date();
    
    const locale = 'en-us';
    
    const wDay   = date.toLocaleString(locale, {weekday: 'short'});
    const month  = date.toLocaleString(locale, {month: 'long'});
    const year   = date.toLocaleString(locale, {year: 'numeric'});
    const minute = date.toLocaleString(locale, {minute: 'numeric'});
    const [hour, ap] = date.toLocaleString(locale, {hour: 'numeric', hour12:true}).split(' ');
    
    let mDay = date.toLocaleString(locale, {day: 'numeric'});
    
    switch(mDay % 10)
    {
        case 1:  mDay += 'st'; break;
        case 2:  mDay += 'nd'; break;
        case 3:  mDay += 'rd'; break;
        default: mDay += 'th'; break;
    }

现在我们已经完成了所有这些,我们可以这样格式化字符串:

    const formatter = (...a) => `${a[0]}, the ${a[1]} of ${a[2]} ${a[3]} at ${a[4]}:${a[5]} ${a[6]}`;
    const formatted = formatter(wDay, mDay, month, year, hour, minute, ap);

我们甚至可以为“格式化程序”函数使用命名参数:

    const formatter = (wDay, mDay, month, year, hour, minute, ap) => `${wDay}, the ${mDay} of ${month} ${year} at ${hour}:${minute} ${ap}`;
    const formatted = formatter(wDay, mDay, month, year, hour, minute, ap);

如果您注意到,上面的JS模板都是回调的结果。如果上面的整段代码都封装在一个预期返回格式化日期的函数中,那么不难想象如何以相同的方式构造一个可以从外部传入的任意“格式化程序”函数。

tl;dr如果将模板文本放在回调中并使用args作为替换,则可以重用它们。

其他回答

我将添加我自己的发现,这些发现是我问过之后发现的:

number_format(用于千位分隔符/货币格式)sprintf(作者同上)

遗憾的是,sprintf似乎不能像.NET的字符串格式那样处理千位分隔符格式。

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

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

我用这个:

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.

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

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

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