我正在寻找一个与C/PHP printf()或C#/Java程序员String.Format()(IFormatProvider for.NET)相当的JavaScript。
目前,我的基本要求是数字的千位分隔符格式,但处理大量组合(包括日期)的格式会很好。
我意识到Microsoft的Ajax库提供了String.Format()的一个版本,但我们不希望该框架的全部开销。
我正在寻找一个与C/PHP printf()或C#/Java程序员String.Format()(IFormatProvider for.NET)相当的JavaScript。
目前,我的基本要求是数字的千位分隔符格式,但处理大量组合(包括日期)的格式会很好。
我意识到Microsoft的Ajax库提供了String.Format()的一个版本,但我们不希望该框架的全部开销。
当前回答
这里是sprintf在JavaScript中的一个最小实现:它只执行“%s”和“%d”,但我为它保留了扩展空间。这对OP来说是无用的,但其他偶然发现这条来自谷歌的线索的人可能会从中受益。
function sprintf() {
var args = arguments,
string = args[0],
i = 1;
return string.replace(/%((%)|s|d)/g, function (m) {
// m is the matched format, e.g. %s, %d
var val = null;
if (m[2]) {
val = m[2];
} else {
val = args[i];
// A switch statement so that the formatter can be extended. Default is %s
switch (m) {
case '%d':
val = parseFloat(val);
if (isNaN(val)) {
val = 0;
}
break;
}
i++;
}
return val;
});
}
例子:
alert(sprintf('Latitude: %s, Longitude: %s, Count: %d', 41.847, -87.661, 'two'));
// Expected output: Latitude: 41.847, Longitude: -87.661, Count: 0
与之前回复中的类似解决方案相比,此解决方案一次性完成所有替换,因此不会替换先前替换值的部分。
其他回答
当前JavaScript
从上的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}}。所以要像恐惧噬菌体的建议那样同时进行替换。
JavaScript有“sprintf”,您可以在http://www.webtoolkit.info/javascript-sprintf.html.
好的,首先我们将设置一些要使用的变量:
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作为替换,则可以重用它们。
我使用一个名为String.format for JavaScript的小型库,它支持大多数格式字符串功能(包括数字和日期格式),并使用.NET语法。脚本本身小于4kB,因此不会产生太多开销。
一个稍有不同的版本,我更喜欢的版本(这个版本使用{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()本地化函数。