我想用JavaScript格式化价格。我想要一个函数,它将浮点作为参数,并返回如下格式的字符串:
"$ 2,500.00"
我该怎么做?
我想用JavaScript格式化价格。我想要一个函数,它将浮点作为参数,并返回如下格式的字符串:
"$ 2,500.00"
我该怎么做?
当前回答
快速快捷的解决方案(适用于任何地方!)
(12345.67).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'); // 12,345.67
此解决方案背后的思想是用第一个匹配和逗号替换匹配的部分,即“$&,”。匹配是使用前瞻方法完成的。您可以将表达式读为“匹配一个数字,如果它后面跟着三个数字集(一个或多个)和一个点的序列”。
测验:
1 --> "1.00"
12 --> "12.00"
123 --> "123.00"
1234 --> "1,234.00"
12345 --> "12,345.00"
123456 --> "123,456.00"
1234567 --> "1,234,567.00"
12345.67 --> "12,345.67"
演示:http://jsfiddle.net/hAfMM/9571/
扩展短解决方案
您还可以扩展Number对象的原型,以添加对任意数量的小数[0..n]和数字组大小[0..x]的额外支持:
/**
* Number.prototype.format(n, x)
*
* @param integer n: length of decimal
* @param integer x: length of sections
*/
Number.prototype.format = function(n, x) {
var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\.' : '$') + ')';
return this.toFixed(Math.max(0, ~~n)).replace(new RegExp(re, 'g'), '$&,');
};
1234..format(); // "1,234"
12345..format(2); // "12,345.00"
123456.7.format(3, 2); // "12,34,56.700"
123456.789.format(2, 4); // "12,3456.79"
演示/测试:http://jsfiddle.net/hAfMM/435/
超扩展短解决方案
在此超级扩展版本中,您可以设置不同的分隔符类型:
/**
* Number.prototype.format(n, x, s, c)
*
* @param integer n: length of decimal
* @param integer x: length of whole part
* @param mixed s: sections delimiter
* @param mixed c: decimal delimiter
*/
Number.prototype.format = function(n, x, s, c) {
var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\D' : '$') + ')',
num = this.toFixed(Math.max(0, ~~n));
return (c ? num.replace('.', c) : num).replace(new RegExp(re, 'g'), '$&' + (s || ','));
};
12345678.9.format(2, 3, '.', ','); // "12.345.678,90"
123456.789.format(4, 4, ' ', ':'); // "12 3456:7890"
12345678.9.format(0, 3, '-'); // "12-345-679"
演示/测试:http://jsfiddle.net/hAfMM/612/
其他回答
javascript数字格式化程序(以前在Google Code)
短、快、灵活但独立。接受标准数字格式,如#、##0.00或带否定的-000.####。接受任何国家/地区格式,如###0,00,#,###.##,#‘###.##或任何类型的非编号符号。接受任意数字分组。#、##、#0.000或#、####0.##均有效。接受任何冗余/万无一失的格式。##、###、##。#或0#、#00####0#都正常。自动数字舍入。简单的界面,只需提供如下掩码和值:格式(“0.0000”,3.141592)。在掩码中包含前缀和后缀
(摘自自述)
我想要一个自动返回小数部分的普通JavaScript解决方案。
function formatDollar(amount) {
var dollar = Number(amount).toLocaleString("us", "currency");
// Decimals
var arrAmount = dollar.split(".");
if (arrAmount.length==2) {
var decimal = arrAmount[1];
if (decimal.length==1) {
arrAmount[1] += "0";
}
}
if (arrAmount.length==1) {
arrAmount.push("00");
}
return "$" + arrAmount.join(".");
}
console.log(formatDollar("1812.2");
乔纳森·M的代码对我来说太复杂了,所以我重写了它,在Firefox v30上获得了30%的速度提升,在Chrome v35上获得了60%的速度提升(http://jsperf.com/number-formating2):
Number.prototype.formatNumber = function(decPlaces, thouSeparator, decSeparator) {
decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
decSeparator = decSeparator == undefined ? "." : decSeparator;
thouSeparator = thouSeparator == undefined ? "," : thouSeparator;
var n = this.toFixed(decPlaces);
if (decPlaces) {
var i = n.substr(0, n.length - (decPlaces + 1));
var j = decSeparator + n.substr(-decPlaces);
} else {
i = n;
j = '';
}
function reverse(str) {
var sr = '';
for (var l = str.length - 1; l >= 0; l--) {
sr += str.charAt(l);
}
return sr;
}
if (parseInt(i)) {
i = reverse(reverse(i).replace(/(\d{3})(?=\d)/g, "$1" + thouSeparator));
}
return i + j;
};
用法:
var sum = 123456789.5698;
var formatted = '$' + sum.formatNumber(2, ',', '.'); // "$123,456,789.57"
在将PHP number_format()转换为javascript之后,这对我很有用
function number_format(number, decimals = 0, dec_point = ".",thousands_sep = ",") {
number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
var n = !isFinite(+number) ? 0 : +number,
prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
s = '',
toFixedFix = function(n, prec)
{
var k = Math.pow(10, prec);
return '' + (Math.round(n * k) / k).toFixed(prec);
};
// Fix for IE parseFloat(0.55).toFixed(0) = 0;
s = (prec ? toFixedFix(n, prec) : '' +
Math.round(n)).split('.');
if (s[0].length > 3)
{
s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g,
thousands_sep);
}
if ((s[1] || '').length < prec)
{
s[1] = s[1] || '';
s[1] += new Array(prec - s[1].length + 1).join('0');
}
return s.join(dec_point);
}
许多答案都有有益的想法,但没有一个能满足我的需求。所以我使用了所有的想法,并构建了这个示例:
function Format_Numb(fmt){
var decimals = isNaN(decimals) ? 2 : Math.abs(decimals);
if(typeof decSgn === "undefined") decSgn = ".";
if(typeof kommaSgn === "undefined") kommaSgn= ",";
var s3digits = /(\d{1,3}(?=(\d{3})+(?=[.]|$))|(?:[.]\d*))/g;
var dflt_nk = "00000000".substring(0, decimals);
//--------------------------------
// handler for pattern: "%m"
var _f_money = function(v_in){
var v = v_in.toFixed(decimals);
var add_nk = ",00";
var arr = v.split(".");
return arr[0].toString().replace(s3digits, function ($0) {
return ($0.charAt(0) == ".")
? ((add_nk = ""), (kommaSgn + $0.substring(1)))
: ($0 + decSgn);
})
+ ((decimals > 0)
? (kommaSgn
+ (
(arr.length > 1)
? arr[1]
: dflt_nk
)
)
: ""
);
}
// handler for pattern: "%<len>[.<prec>]f"
var _f_flt = function(v_in, l, prec){
var v = (typeof prec !== "undefined") ? v_in.toFixed(prec) : v_in;
return ((typeof l !== "undefined") && ((l=l-v.length) > 0))
? (Array(l+1).join(" ") + v)
: v;
}
// handler for pattern: "%<len>x"
var _f_hex = function(v_in, l, flUpper){
var v = Math.round(v_in).toString(16);
if(flUpper) v = v.toUpperCase();
return ((typeof l !== "undefined") && ((l=l-v.length) > 0))
? (Array(l+1).join("0") + v)
: v;
}
//...can be extended..., just add the function, for example: var _f_octal = function( v_in,...){
//--------------------------------
if(typeof(fmt) !== "undefined"){
//...can be extended..., just add the char, for example "O": MFX -> MFXO
var rpatt = /(?:%([^%"MFX]*)([MFX]))|(?:"([^"]*)")|("|%%)/gi;
var _qu = "\"";
var _mask_qu = "\\\"";
var str = fmt.toString().replace(rpatt, function($0, $1, $2, $3, $4){
var f;
if(typeof $1 !== "undefined"){
switch($2.toUpperCase()){
case "M": f = "_f_money(v)"; break;
case "F": var n_dig0, n_dig1;
var re_flt =/^(?:(\d))*(?:[.](\d))*$/;
$1.replace(re_flt, function($0, $1, $2){
n_dig0 = $1;
n_dig1 = $2;
});
f = "_f_flt(v, " + n_dig0 + "," + n_dig1 + ")"; break;
case "X": var n_dig = "undefined";
var re_flt = /^(\d*)$/;
$1.replace(re_flt, function($0){
if($0 != "") n_dig = $0;
});
f = "_f_hex(v, " + n_dig + "," + ($2=="X") + ")"; break;
//...can be extended..., for example: case "O":
}
return "\"+"+f+"+\"";
} else if(typeof $3 !== "undefined"){
return _mask_qu + $3 + _mask_qu;
} else {
return ($4 == _qu) ? _mask_qu : $4.charAt(0);
}
});
var cmd = "return function(v){"
+ "if(typeof v === \"undefined\")return \"\";" // null returned as empty string
+ "if(!v.toFixed) return v.toString();" // not numb returned as string
+ "return \"" + str + "\";"
+ "}";
//...can be extended..., just add the function name in the 2 places:
return new Function("_f_money,_f_flt,_f_hex", cmd)(_f_money,_f_flt,_f_hex);
}
}
首先,我需要一个C样式格式的字符串定义,它应该是灵活的,但非常容易使用,我用以下方式定义它:;模式:
%[<len>][.<prec>]f float, example "%f", "%8.2d", "%.3f"
%m money
%[<len>]x hexadecimal lower case, example "%x", "%8x"
%[<len>]X hexadecimal upper case, example "%X", "%8X"
因为对我来说,除了欧元之外,没有任何其他格式的需要,所以我只实现了“%m”。
但这很容易扩展。。。与C中一样,格式字符串是包含模式的字符串。例如,对于欧元:“%m€”(返回类似“8.129,33€”的字符串)
除了灵活性之外,我还需要一个处理表的快速解决方案。这意味着,在处理数千个单元格时,格式字符串的处理不能重复一次。我不接受类似“format(value,fmt)”的调用,但这必须分为两个步骤:
// var formatter = Format_Numb( "%m €");
// simple example for Euro...
// but we use a complex example:
var formatter = Format_Numb("a%%%3mxx \"zz\"%8.2f°\" >0x%8X<");
// formatter is now a function, which can be used more than once (this is an example, that can be tested:)
var v1 = formatter(1897654.8198344);
var v2 = formatter(4.2);
... (and thousands of rows)
同样为了提高性能,_f_money包含正则表达式;
第三,类似“format(value,fmt)”的调用是不可接受的,因为:
虽然可以用不同的掩码格式化不同的对象集合(例如,列的单元格),但我不想在处理时处理格式化字符串。此时,我只想使用格式,如
for(单元格中的var单元格){do_something(cell.col.formatter(cell.value));}
什么格式-可能是在.ini文件中,在XML中为每一列或其他地方定义的。。。,但是分析和设置格式或处理国际化完全是在另一个地方进行的,在那里我想将格式化程序分配给集合,而不考虑性能问题:
col.formatter=格式_字符串(_getFormatForColumn(…));
第四,我想要一个“宽容”的解决方案,因此传递例如字符串而不是数字应该只返回字符串,但“null”应该返回一个空字符串。
(如果值太大,格式化“%4.2f”也不能剪切。)
最后,但并非最不重要的是,它应该是可读的,易于扩展,而不会对性能产生任何影响。。。例如,如果某人需要“八进制值”,请参考带有“…可以扩展…”的行-我认为这应该是一项非常简单的任务。
我的整体重点是表现。每个“处理例程”(例如,_f_money)都可以被封装优化,或者在这个或其他线程中与其他思想进行交换,而无需更改“准备例程”(分析格式字符串和创建函数),这些例程只能被处理一次,从这个意义上说,与数千个数字的转换调用相比,性能并不那么关键。
对于所有喜欢数字方法的人来说:
Number.prototype.format_euro = (function(formatter){
return function(){ return formatter(this); }})
(Format_Numb( "%m €"));
var v_euro = (8192.3282).format_euro(); // results: 8.192,33 €
Number.prototype.format_hex = (function(formatter){
return function(){ return formatter(this); }})
(Format_Numb( "%4x"));
var v_hex = (4.3282).format_hex();
虽然我测试了一些,但代码中可能有很多错误。因此,它不是一个现成的模块,只是像我这样的非JavaScript专家的一个想法和起点。
该代码包含了许多StackOverflow帖子中修改过的想法;很抱歉,我不能引用所有这些,但感谢所有的专家。