我正在寻找一个良好的JavaScript等价物来替代C/PHP中的printf()
或对于C#/Java程序员,String.Format()
(.NET使用 IFormatProvider
)。
我的基本要求是数字的千位分隔符格式,但能处理许多组合(包括日期)的东西会更好。
我意识到微软的Ajax库提供了一个版本的String.Format()
,但我们不想要整个框架的开销。
我正在寻找一个良好的JavaScript等价物来替代C/PHP中的printf()
或对于C#/Java程序员,String.Format()
(.NET使用 IFormatProvider
)。
我的基本要求是数字的千位分隔符格式,但能处理许多组合(包括日期)的东西会更好。
我意识到微软的Ajax库提供了一个版本的String.Format()
,但我们不想要整个框架的开销。
从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}
。因此建议使用类似于fearphage的建议中的同时替换方法。
num.toFixed()
方法就足够了! - heltonbiker在之前提出的解决方案基础上进行改进:
// 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}
+
运算符),请确保将完整的字符串放在括号中:("asd {0}"+"fas {1}").format("first", "second");
否则,此函数仅会应用于最后一个被附加的字符串。 - Lukas Knuth'foo {0}'.format(fnWithNoReturnValue())
,当前它会返回foo {0}
。通过你的修改,它将返回foo undefined
。 - fearphagesprintf()
更好,因为它基本上做的是相同的事情,并且非常小巧。(原文已经是英文) - user2233706有趣的是,Stack Overflow实际上为String
原型创建了自己的格式化函数,名为formatUnicorn
。试试看吧!进入控制台并输入类似以下内容:
"Hello, {name}, are you feeling {adjective}?".formatUnicorn({name:"Gabriel", adjective: "OK"});
你会得到这个输出:
你好,Gabriel,你感觉还好吗?
你可以使用对象、数组和字符串作为参数!我获取了它的代码并重新制作了一个新版本的 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
的slice
会强制将arguments
中的任何内容转换为Array
,无论它最初的形式如何,而key
将是每个数组元素的索引(0、1、2......)被强制转换为一个字符串(例如,"0",所以你的第一个正则表达式模式为"\\{0\\}"
)。很不错。g
),可以替换多个相同的关键字。在上面的例子中,您可以在同一句子中多次使用 {name}
并将它们全部替换。 - KrekkieDname
是 "blah {adjective} blah"
,会发生什么? - sam hocevar我来到这个问题页面,希望找到如何在JavaScript中格式化数字,而不引入另一个库。这是我找到的内容:
在JavaScript中,相当于sprintf("%.2f", num)
的方法似乎是num.toFixed(2)
,它将num
格式化为两位小数,并进行四舍五入(但请查看@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
Mozilla toFixed()参考页面(包含链接到toPrecision(),toExponential(),toLocaleString()等)
..
也可以使用:33333..toExponential(2);
- Peter Jaric从 ES6 开始,您可以使用模板字符串:
let soMany = 10;
console.log(`This is ${soMany} times easier!`);
// "This is 10 times easier!"
https://developers.google.com/web/updates/2015/01/ES6-Template-Strings
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings
注意: 请查看Mozilla网站以获取支持的浏览器列表。
const compile = (x, y) => \
我可以随时调用这个模板字符串.. x=${x}, y=${y}`...
compile(30, 20)` - cchamberlainjsxt,Zippo
这个选项更加合适。
String.prototype.format = function() {
var formatted = this;
for (var i = 0; i < arguments.length; i++) {
var regexp = new RegExp('\\{'+i+'\\}', 'gi');
formatted = formatted.replace(regexp, arguments[i]);
}
return formatted;
};
通过此选项,我可以替换这样的字符串:
'The {0} is dead. Don\'t code {0}. Code {1} that is open source!'.format('ASP', 'PHP');
对于 Node.js 用户,可以使用类似printf的功能的util.format
util.format("%s world", "Hello")
%-20s %5.2f
)。 - FGM我使用这个简单的函数:
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")
for...in
在某些浏览器中无法按照此代码所期望的方式工作。它将循环遍历所有可枚举属性,在某些浏览器中包括arguments.length
,而在其他浏览器中甚至不包括参数本身。无论如何,如果添加了Object.prototype
,任何添加都可能被包含在其中。该代码应该使用标准的for
循环,而不是 for...in
。 - cHao"{0} is dead, but {1} is alive!".format("{1}", "ASP.NET") === "ASP.NET is dead, but ASP.NET is alive!"
- Gumboarg
是全局的。你需要使用以下代码替换:for (var arg in arguments) {
。 - Pauan{n}
:'{0}'.format('you should only see this {1}', 'you should not see this')
- Marian我很惊讶没有人使用reduce
,这是一个原生并且简洁、强大的JavaScript函数。
String.prototype.format = function() {
return [...arguments].reduce((p,c) => p.replace(/%s/,c), this);
};
console.log('Is that a %s or a %s?... No, it\'s %s!'.format('plane', 'bird', 'SOman'));
function interpolate(theString, argumentArray) {
var regex = /%s/;
var _r=function(p,c){return p.replace(regex,c);}
return argumentArray.reduce(_r, theString);
}
interpolate("%s, %s and %s", ["Me", "myself", "I"]); // "Me, myself and I"
工作原理:
reduce函数将一个函数应用于累加器和数组中的每个元素(从左到右),将其减少为单个值。
var _r= function(p,c){return p.replace(/%s/,c)};
console.log(
["a", "b", "c"].reduce(_r, "[%s], [%s] and [%s]") + '\n',
[1, 2, 3].reduce(_r, "%s+%s=%s") + '\n',
["cool", 1337, "stuff"].reduce(_r, "%s %s %s")
);
printf
函数的版本:https://jsfiddle.net/11szrbx9 - Dem Pilafian(...a) => {return a.reduce((p: string, c: any) => p.replace(/%s/, c));
- dtasevString.prototype.format
:((a,b,c)=>\
${a}, ${b}和${c}`)(...['我', '自己', '我自己'])`(请注意,这有点冗余,以更好地适应您的示例) - Tinoprintf
的每个类型说明符实现替换函数,并包含填充前缀的逻辑。以明智的方式迭代格式字符串似乎是次要的挑战,我认为这是一个整洁的解决方案,如果你只需要字符串替换的话。 - collapsar这是JavaScript中sprintf函数的最小实现:它只支持 "%s" 和 "%d",但我留出了扩展空间。对于OP来说是无用的,但其他从Google搜索进入此线程的人可能会受益。
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
与先前回复中类似的解决方案相比,这个解决方案会一次性完成所有替换操作,因此不会替换先前已经被替换过的值的部分。
String.padStart
。 (请参见https://dev59.com/jXE85IYBdhLWcg3wnU-p) - Nor.Z