console.log(pyformat( 'The {} {} jumped over the {}'
, ['brown' ,'fox' ,'foobar']
))
console.log(pyformat('The {0} {1} jumped over the {1}'
, ['brown' ,'fox' ,'foobar']
))
console.log(pyformat('The {color} {animal} jumped over the {thing}'
, [] ,{color: 'brown' ,animal: 'fox' ,thing: 'foobaz'}
))
2
/**
* Format string by replacing placeholders with value from element with
* corresponsing index in `replacementArray`.
* Replaces are made simultaneously, so that replacement values like
* '{1}' will not mess up the function.
*
* Example 1:
* ('{2} {1} {0}', ['three', 'two' ,'one']) -> 'one two three'
*
* Example 2:
* ('{0}{1}', ['{1}', '{0}']) -> '{1}{0}'
*/
function stringFormat(formatString, replacementArray) {
return formatString.replace(
/\{(\d+)\}/g, // Matches placeholders, e.g. '{1}'
function formatStringReplacer(match, placeholderIndex) {
// Convert String to Number
placeholderIndex = Number(placeholderIndex);
// Make sure that index is within replacement array bounds
if (placeholderIndex < 0 ||
placeholderIndex > replacementArray.length - 1
) {
return placeholderIndex;
}
// Replace placeholder with value from replacement array
return replacementArray[placeholderIndex];
}
);
}
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;
});
}
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'));
<ES6
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"
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."
30 回答
我没有在列表中看到pyformat所以我以为我会把它扔进去:
对于Node.js用户,util.format具有类似printf的功能:
为了防止有人需要一个函数来防止污染全局范围,这里的功能是相同的:
JavaScript中的数字格式
我到了这个问题页面,希望在JavaScript中找到如何 format numbers ,而不引入另一个库 . 这里's what I'发现:
舍入浮点数
在JavaScript中等效的
sprintf("%.2f", num)
似乎是num.toFixed(2)
,它将num
格式化为2位小数,并进行舍入(但请参阅@ ars265关于Math.round
的注释) .指数形式
相当于
sprintf("%.2e", num)
是num.toExponential(2)
.十六进制和其他基础
要在基数B中打印数字,请尝试
num.toString(B)
. JavaScript支持自动转换到基数2到36(此外,某些浏览器有limited support for base64 encoding) .参考页面
Quick tutorial on JS number formatting
Mozilla reference page for toFixed()(链接到toPrecision(),toExponential(),toLocaleString(),...)
PHPJS project为许多PHP编写了JavaScript实现's functions. Since PHP' s
sprintf()
函数与C的printf()
基本相同,their JavaScript implementation of it应该满足您的需求 .从ES6上你可以使用 template strings :
请注意,模板字符串是 surrounded by backticks `而不是(单个)引号 .
了解更多信息:
https://developers.google.com/web/updates/2015/01/ES6-Template-Strings
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings
注意:检查mozilla-site以查找支持的浏览器列表 .
jsxt,Zippo
此选项更适合 .
使用此选项,我可以替换这些字符串:
使用您的代码,第二个{0}将不会被替换 . ;)
我有一个稍长的JavaScript格式化程序here ...
你可以用几种方式格式化:
String.format(input, args0, arg1, ...)
String.format(input, obj)
"literal".format(arg0, arg1, ...)
"literal".format(obj)
此外,如果您说ObjectBase.prototype.format(例如DateJS),它将使用它 .
例子...
我也使用.asFormat别名并且已经有一些检测,以防已经有一个string.format(例如使用MS Ajax Toolkit(我讨厌那个库) .
对于基本格式:
我会添加自己的发现,因为我问过:
number_format (for thousand separator/currency formatting)
sprintf (same author as above)
可悲的是,似乎sprintf没有像.NET的字符串格式那样处理千位分隔符格式 .
这是JavaScript中sprintf的最小实现:它只有"%s"和"%d",但我留下了空间来扩展它 . 它对OP来说毫无用处,但是偶然发现来自Google的这个帖子的其他人可能会从中受益 .
例:
与之前回复中的类似解决方案相比,这个解决方案一次完成所有替换,因此它不会替换先前替换的值的部分 .
我很惊讶没有人使用reduce,这是一个原生简洁而强大的JavaScript功能 .
ES6(EcmaScript2015)
<ES6
这个怎么运作:
添加到
zippoxer
的答案,我使用此功能:我还有一个非原型版本,我经常使用它的Java语法:
ES 2015更新
ES 2015中所有酷炫的新东西都让这更容易:
我认为,因为这与旧版本一样,实际上并不解析字母,所以也可以只使用一个令牌
%%
. 这样做的好处是显而易见,并且不会使单个%
变得困难 . 但是,如果由于某种原因需要%%
,则需要将其替换为自身:我想分享我对“问题”的解决方案 . 我没有重新发明轮子,但试图找到一个基于JavaScript已经做的解决方案 . 优点是,您可以免费获得所有隐式转换 . 设置String的prototype属性$给出了非常好的紧凑语法(参见下面的示例) . 它可能不是最有效的方式,但在大多数情况下处理输出它不必进行超级优化 .
这里有一些例子:
一个非常不同的版本,我更喜欢的版本(这个版本使用令牌而不是{0}编号的参数,这更加自我记录,更适合本地化):
变化将是:
首先调用l()本地化函数 .
我用这个:
然后我称之为:
这很有趣,因为Stack Overflow实际上有一个名为
formatUnicorn
的String
原型的格式化函数 . 试试吧!进入控制台并键入以下内容:你得到这个输出:
Hello, Gabriel, are you feeling OK?
您可以使用对象,数组和字符串作为参数!我得到了它的代码并重新编写它以生成
String.prototype.format
的新版本:注意聪明的
Array.prototype.slice.call(arguments)
调用 - 这意味着如果你抛出的是字符串或数字的参数,而不是单个JSON样式的对象,你几乎可以得到C#的String.Format行为 .这是因为
Array
的slice
将强制arguments
中的任何内容进入Array
,无论它是否原来,并且key
将是每个数组元素强制转换为字符串的索引(0,1,2 ......)(例如, "0",所以"\\{0\\}"
为您的第一个正则表达式模式) .整齐 .
我用这个简单的功能:
这与string.format非常相似:
JavaScript程序员可以在https://github.com/ildar-shaimordanov/jsxt/blob/master/js/String.js使用String.prototype.sprintf . 以下是示例:
您可以在http://www.webtoolkit.info/javascript-sprintf.html找到JavaScript的"sprintf" .
如果您希望处理千位分隔符,您应该使用JavaScript Number类中的toLocaleString(),因为它将格式化用户区域的字符串 .
JavaScript Date类可以格式化本地化的日期和时间 .
对于那些喜欢Node.JS及其util.format功能的人,我只是把它提取到它的vanilla JavaScript表单中(只有util.format使用的函数):
收获自:https://github.com/joyent/node/blob/master/lib/util.js
1 Zippo,但函数体需要如下所示,否则它会在每次迭代时附加当前字符串:
我没有看到
String.format
变种:基于之前建议的解决方案:
"{0} is dead, but {1} is alive! {0} {2}".format("ASP", "ASP.NET")
输出
如果你不想修改
String
的原型:给你更熟悉的东西:
String.format('{0} is dead, but {1} is alive! {0} {2}', 'ASP', 'ASP.NET');
结果相同:
十分优雅:
信用转到(断开链接)https://gist.github.com/0i0/1519811
编辑:从ES6开始,您可以使用模板字符串:
有关详细信息,请参阅下面的Kim的answer .
原始答案:
试试sprintf() for JavaScript .
Update 好的,如果你真的想自己做一个简单的格式化方法,不要连续进行替换,而是同时进行 .
因为当前替换的替换字符串也包含如下格式序列时,提及的大多数其他提议都会失败:
通常您会期望输出为
{1}{0}
但实际输出为{1}{1}
. 所以做一个同时替换,而不是像fearphage’s suggestion .我有一个非常接近彼得的解决方案,但它涉及数字和对象的情况 .
也许处理所有深层次的情况可能更好,但是对于我的需求,这很好 .
PS:如果您在AngularJS之类的模板框架中使用翻译,这个功能非常酷:
en.json就像是
我使用一个名为String.format for JavaScript的小型库,它支持大多数格式字符串功能(包括数字和日期的格式),并使用.NET语法 . 脚本本身小于4 kB,因此不会产生太多开销 .