我正在寻找一个与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()的一个版本,但我们不希望该框架的全部开销。
当前回答
如果您希望处理千位分隔符,那么应该真正使用JavaScript Number类中的toLocaleString(),因为它将为用户所在区域设置字符串格式。
JavaScript Date类可以格式化本地化的日期和时间。
其他回答
JavaScript中的数字格式
我来到这个问题页面,希望找到如何在JavaScript中格式化数字,而不引入另一个库。以下是我的发现:
舍入浮点数
JavaScript中sprintf(“%.2f”,num)的等价物似乎是num.toFixed(2),它将num格式化为2位小数,并带舍入(但请参见@ars265下面关于Math.round的评论)。
(12.345).toFixed(2); // returns "12.35" (rounding!)
(12.3).toFixed(2); // returns "12.30" (zero padding)
指数形式
sprintf(“%.2e”,num)的等效值为num.toExponential(2)。
(33333).toExponential(2); // "3.33e+4"
十六进制和其他基数
要以基数B打印数字,请尝试num.toString(B)。JavaScript支持从基数2到36的自动转换(此外,某些浏览器对base64编码的支持有限)。
(3735928559).toString(16); // to base 16: "deadbeef"
parseInt("deadbeef", 16); // from base 16: 3735928559
参考页
JS数字格式快速教程
toFixed()的Mozilla参考页(带有指向Precision()、toExponential()、toLocaleString()等的链接)
我想分享我对“问题”的解决方案。我没有重新发明轮子,但试图根据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'
String.prototype.repeat = function(n) {
return new Array(++n).join(this);
};
String.prototype.pad = function(requiredLength, paddingStr, paddingType) {
var n = requiredLength - this.length;
if (n) {
paddingType = paddingType ? paddingType.toLowerCase() : '';
paddingStr = paddingStr || ' ';
paddingStr = paddingStr.repeat( Math.ceil(n / paddingStr.length) ).substr(0, n);
if (paddingType == 'both') {
n /= 2;
return paddingStr.substr( 0, Math.ceil(n) ) + this + paddingStr.substr( 0, Math.floor(n) );
}
if (paddingType == 'left') {
return paddingStr + this;
}
return this + paddingStr;
}
return this;
};
// синтаксис аналогичен printf
// 'Привет, %s!'.format('мир') -> "Привет, мир!"
// '%.1s.%.1s. %s'.format('Иван', 'Иванович', 'Иванов') -> "И.И. Иванов"
String.prototype.format = function() {
var i = 0,
params = arguments;
return this.replace(/%(?:%|(?:(|[+-]+)(|0|'.+?)([1-9]\d*)?(?:\.([1-9]\d*))?)?(s|d|f))/g, function(match, sign, padding, width, precision, type) {
if (match == '%%') {
return '%';
}
var v = params[i++];
if (type == 'd') {
v = Math.round(v);
}
else if (type == 'f') {
v = v.toFixed(precision ? precision : 6);
}
if (/\+/.test(sign) && v > 0) {
v = '+' + v;
}
v += '';
if (type != 'f' && precision) {
v = v.substr(0, precision);
}
if (width) {
v = v.pad(width, padding == '' ? ' ' : padding[0] == "'" ? padding.substr(1) : padding, /-/.test(sign) ? 'right' : 'left');
}
return v;
});
};
// this.name = 'Вася';
// console.log( 'Привет, ${name}!'.template(this) );
// "Привет, Вася!"
String.prototype.template = function(context) {
return this.replace(/\$\{(.*?)\}/g, function(match, name) {
return context[name];
});
};
使用Lodash,您可以获得模板功能:
使用ES模板文本分隔符作为“插入”分隔符。通过替换“interpole”分隔符禁用支持。
var compiled = _.template('hello ${ user }!');
compiled({ 'user': 'pebbles' });
// => 'hello pebbles!
bobjs可以做到这一点:
var sFormat = "My name is {0} and I am {1} years old.";
var result = bob.string.formatString(sFormat, "Bob", 29);
console.log(result);
//output:
//==========
// My name is Bob and I am 29 years old.