我正在寻找一个与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()的一个版本,但我们不希望该框架的全部开销。
当前回答
在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(“世界”));
其他回答
对于Node.js用户,util.format具有类似printf的功能:
util.format("%s world", "Hello")
我将添加我自己的发现,这些发现是我问过之后发现的:
number_format(用于千位分隔符/货币格式)sprintf(作者同上)
遗憾的是,sprintf似乎不能像.NET的字符串格式那样处理千位分隔符格式。
基于先前建议的解决方案:
// First, checks if it isn't implemented yet.
if (!String.prototype.format) {
String.prototype.format = function() {
var args = arguments;
return this.replace(/{(\d+)}/g, function(match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
}
“{0}已死亡,但{1}仍活着!{0{{2}”.format(“ASP”,“ASP.NET”)
输出
ASP死了,但ASP.NET活了!ASP{2}
如果您不想修改String的原型:
if (!String.format) {
String.format = function(format) {
var args = Array.prototype.slice.call(arguments, 1);
return format.replace(/{(\d+)}/g, function(match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
}
让您更加熟悉:
String.format(“{0}无效,但{1}有效!{0{{2}”,“ASP”,“ASP.NET”);
结果相同:
ASP死了,但ASP.NET活了!ASP{2}
这很有趣,因为Stack Overflow实际上有自己的格式化函数,用于名为formatUnicorn的String原型。试试看!进入控制台并键入以下内容:
"Hello, {name}, are you feeling {adjective}?".formatUnicorn({name:"Gabriel", adjective: "OK"});
您将获得以下输出:
你好,加布里埃尔,你感觉还好吗?
您可以使用对象、数组和字符串作为参数!我得到了它的代码并对其进行了修改,以生成String.prototype.format的新版本:
String.prototype.formatUnicorn = String.prototype.formatUnicorn ||
function () {
"use strict";
var str = this.toString();
if (arguments.length) {
var t = typeof arguments[0];
var key;
var args = ("string" === t || "number" === t) ?
Array.prototype.slice.call(arguments)
: arguments[0];
for (key in args) {
str = str.replace(new RegExp("\\{" + key + "\\}", "gi"), args[key]);
}
}
return str;
};
请注意,巧妙的Array.prototype.slice.call(arguments)调用——这意味着如果你输入的参数是字符串或数字,而不是一个JSON样式的对象,那么你几乎可以得到C#的String.Format行为。
"a{0}bcd{1}ef".formatUnicorn("FOO", "BAR"); // yields "aFOObcdBARef"
这是因为Array的切片会将参数中的任何内容强制到Array中,无论它最初是不是这样,并且关键字将是每个数组元素的索引(0,1,2…),该索引被强制到字符串中(例如,“0”,因此第一个正则表达式模式为“\\{0\\}”)。
整洁的
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];
});
};