我正在寻找一个与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已经做的事情找到解决方案。优点是,您可以免费获得所有隐式转换。设置字符串的原型属性$提供了一个非常好和紧凑的语法(参见下面的示例)。这可能不是最有效的方法,但在大多数情况下,处理输出时不必进行超级优化。
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'
其他回答
JavaScript有“sprintf”,您可以在http://www.webtoolkit.info/javascript-sprintf.html.
除了zippoxer的答案,我还使用了这个函数:
String.prototype.format = function () {
var a = this, b;
for (b in arguments) {
a = a.replace(/%[a-z]/, arguments[b]);
}
return a; // Make chainable
};
var s = 'Hello %s The magic number is %d.';
s.format('world!', 12); // Hello World! The magic number is 12.
我还有一个非原型版本,我经常使用它的类似Java的语法:
function format() {
var a, b, c;
a = arguments[0];
b = [];
for(c = 1; c < arguments.length; c++){
b.push(arguments[c]);
}
for (c in b) {
a = a.replace(/%[a-z]/, b[c]);
}
return a;
}
format('%d ducks, 55 %s', 12, 'cats'); // 12 ducks, 55 cats
ES 2015更新
ES 2015中所有酷炫的新功能让这一切变得更加简单:
function format(fmt, ...args){
return fmt
.split("%%")
.reduce((aggregate, chunk, i) =>
aggregate + chunk + (args[i] || ""), "");
}
format("Hello %%! I ate %% apples today.", "World", 44);
// "Hello World, I ate 44 apples today."
我想,因为这和以前的一样,实际上并不能解析字母,所以最好只使用一个标记%%。这样做的好处是显而易见的,并且不会使使用单一的%变得困难。但是,如果出于某种原因需要%%,则需要将其替换为自身:
format("I love percentage signs! %%", "%%");
// "I love percentage signs! %%"
对于基本格式:
var template = jQuery.validator.format("{0} is not a valid value");
var result = template("abc");
在typescript中,创建一个名为format.ts的文件,并导入您需要使用的任何格式。
// contents of format.ts
interface String {
format(...args: any[]): string;
}
if (!String.prototype.format) {
String.prototype.format = function() {
let a = this;
let b: any;
// tslint:disable-next-line: forin
for (b in arguments) {
a = a.replace(/%[a-z]/, arguments[b]);
}
return a;
};
}
要格式化字符串,请使用以下代码:
import './format';
console.log('Hello, %s!'.format('World'));
实例
String.prototype.format=函数(){设a=此;设b;for(参数中的b){a=a.replace(/%[a-z]/,自变量[b]);}返回a;};console.log(“您好,%s!”.format(“世界”));
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