我正在寻找一个与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()的一个版本,但我们不希望该框架的全部开销。
当前回答
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];
});
};
其他回答
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
虽然不是世界上最推荐的功能,但它确实有效。
如果需要sprintf,只需复制并粘贴相同的函数,并将return console.log(sb)更改为只返回sb。
printf=函数(s,/*args…*/){a=参数;al=a.length;如果(al<=1)返回-2;如果(al>=2&&s.toLowerCase().search(/%[a-z]/)==-1)返回-1;sb=s;对于(i=1;i<=al-1;i++){sb=某人替换(/%[a-z]/,a[i]);}返回控制台日志(sb);}var someString=“您好%s\n现在是%s:%s%s。\n今天是%s\n”;printf(someString,“StackOverflowUser”,“5”,“48”,“PM”,“漂亮”);
我使用这个简单的函数:
String.prototype.format = function() {
var formatted = this;
for( var arg in arguments ) {
formatted = formatted.replace("{" + arg + "}", arguments[arg]);
}
return formatted;
};
这与string.format非常相似:
"{0} is dead, but {1} is alive!".format("ASP", "ASP.NET")
为了防止有人需要一个功能来防止污染全球范围,下面是一个功能:
function _format (str, arr) {
return str.replace(/{(\d+)}/g, function (match, number) {
return typeof arr[number] != 'undefined' ? arr[number] : match;
});
};
一个稍有不同的版本,我更喜欢的版本(这个版本使用{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()本地化函数。