How can I format numbers as dollars currency string in JavaScript?
我想用javascript格式化价格。我想要一个函数,它以一个
1 | "$ 2,500.00" |
最好的方法是什么?
编号.原型.tofixed
此解决方案与每个主要浏览器都兼容:
1 2 3 4 5 | const profits = 2489.8237; profits.toFixed(3) //returns 2489.824 (rounds up) profits.toFixed(2) //returns 2489.82 profits.toFixed(7) //returns 2489.8237000 (pads the decimals) |
您只需添加货币符号(如
如果需要在每个数字之间使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function formatMoney(n, c, d, t) { var c = isNaN(c = Math.abs(c)) ? 2 : c, d = d == undefined ?"." : d, t = t == undefined ?"," : t, s = n < 0 ?"-" :"", i = String(parseInt(n = Math.abs(Number(n) || 0).toFixed(c))), j = (j = i.length) > 3 ? j % 3 : 0; return s + (j ? i.substr(0, j) + t :"") + i.substr(j).replace(/(\d{3})(?=\d)/g,"$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) :""); }; document.getElementById("b").addEventListener("click", event => { document.getElementById("x").innerText ="Result was:" + formatMoney(document.getElementById("d").value); }); |
1 2 3 4 5 | <label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label> <br /> <button id="b">Get Output</button> <p id="x">(press button to get output) </p> |
像这样使用它:
1 | (123456789.12345).formatMoney(2,".",","); |
如果您总是要使用"."和",",您可以将它们从方法调用中去掉,并且该方法将为您默认它们。
1 | (123456789.12345).formatMoney(2); |
如果您的文化中有两个符号翻转(即欧洲人),并且您希望使用默认值,只需在
1 2 | d = d == undefined ?"," : d, t = t == undefined ?"." : t, |
自定义函数(ES6)
如果您可以使用现代ECMAScript语法(即通过babel),则可以使用这个更简单的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | function formatMoney(amount, decimalCount = 2, decimal =".", thousands =",") { try { decimalCount = Math.abs(decimalCount); decimalCount = isNaN(decimalCount) ? 2 : decimalCount; const negativeSign = amount < 0 ?"-" :""; let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString(); let j = (i.length > 3) ? i.length % 3 : 0; return negativeSign + (j ? i.substr(0, j) + thousands : '') + i.substr(j).replace(/(\d{3})(?=\d)/g,"$1" + thousands) + (decimalCount ? decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) :""); } catch (e) { console.log(e) } }; document.getElementById("b").addEventListener("click", event => { document.getElementById("x").innerText ="Result was:" + formatMoney(document.getElementById("d").value); }); |
1 2 3 4 5 | <label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label> <br /> <button id="b">Get Output</button> <p id="x">(press button to get output) </p> |
短而快速的解决方案(适用于所有地方!)
1 | (12345.67).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'); // 12,345.67 |
这个解决方案背后的想法是用第一个匹配和逗号替换匹配的部分,即
测验:
1 2 3 4 5 6 7 8 | 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/
扩展短解您还可以扩展
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /** * 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/
超长短解在此超级扩展版本中,您可以设置不同的分隔符类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /** * 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有一个数字格式化程序(国际化API的一部分)。
1 2 3 4 5 6 7 | // Create our number formatter. var formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', }); formatter.format(2500); /* $2,500.00 */ |
JS小提琴
使用
最后一个注释,将其与旧的.
1 2 3 4 | (2500).toLocaleString('en-US', { style: 'currency', currency: 'USD', }); /* $2,500.00 */ |
关于浏览器支持的一些说明
- 现在浏览器支持已不再是一个问题,在美国/欧盟有97%的支持率
- 对于世界其他地区(92%的支持率),在支持方面最大的违规者是UC Mobile(远离它)和Opera Mini(因设计而瘫痪)。
- 有一个填充程序可以在旧浏览器上支持它
- 了解更多信息
看看javascript数字对象,看看它是否能帮助您。
toLocaleString() 将使用特定位置的千位分隔符来格式化数字。toFixed() 将数字四舍五入到指定的小数位数。
要同时使用这些,值的类型必须改回数字,因为它们都输出字符串。
例子:
1 | Number(someNumber.toFixed(1)).toLocaleString() |
下面是patrick desjardins(别名daok)代码,添加了一些注释和一些小改动:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /* decimal_sep: character used as deciaml separtor, it defaults to '.' when omitted thousands_sep: char used as thousands separator, it defaults to ',' when omitted */ Number.prototype.toMoney = function(decimals, decimal_sep, thousands_sep) { var n = this, c = isNaN(decimals) ? 2 : Math.abs(decimals), //if decimal is zero we must take it, it means user does not want to show any decimal d = decimal_sep || '.', //if no decimal separator is passed we use the dot as default decimal separator (we MUST use a decimal separator) /* according to [https://stackoverflow.com/questions/411352/how-best-to-determine-if-an-argument-is-not-sent-to-the-javascript-function] the fastest way to check for not defined parameter is to use typeof value === 'undefined' rather than doing value === undefined. */ t = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, //if you don't want to use a thousands separator you can pass empty string as thousands_sep value sign = (n < 0) ? '-' : '', //extracting the absolute value of the integer part of the number and converting to string i = parseInt(n = Math.abs(n).toFixed(c)) + '', j = ((j = i.length) > 3) ? j % 3 : 0; return sign + (j ? i.substr(0, j) + t : '') + i.substr(j).replace(/(\d{3})(?=\d)/g,"$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : ''); } |
这里有一些测试:
1 2 3 4 5 6 7 8 9 10 11 12 | //some tests (do not forget parenthesis when using negative numbers and number with no decimals) alert(123456789.67392.toMoney() + ' ' + 123456789.67392.toMoney(3) + ' ' + 123456789.67392.toMoney(0) + ' ' + (123456).toMoney() + ' ' + (123456).toMoney(0) + ' ' + 89.67392.toMoney() + ' ' + (89).toMoney()); //some tests (do not forget parenthesis when using negative numbers and number with no decimals) alert((-123456789.67392).toMoney() + ' ' + (-123456789.67392).toMoney(-3)); |
次要变化包括:
移动一点
我们使用
不需要
JS小提琴
accounting.js是一个用于数字、货币和货币格式的小型JavaScript库。
如果金额是数字,比如
1 | amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' }); |
将生成字符串
下面是一个完整的工作示例。
这是我见过的最好的JS货币格式化工具:
1 2 3 4 5 6 7 8 9 10 | Number.prototype.formatMoney = function(decPlaces, thouSeparator, decSeparator) { var n = this, decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces, decSeparator = decSeparator == undefined ?"." : decSeparator, thouSeparator = thouSeparator == undefined ?"," : thouSeparator, sign = n < 0 ?"-" :"", i = parseInt(n = Math.abs(+n || 0).toFixed(decPlaces)) +"", j = (j = i.length) > 3 ? j % 3 : 0; return sign + (j ? i.substr(0, j) + thouSeparator :"") + i.substr(j).replace(/(\d{3})(?=\d)/g,"$1" + thouSeparator) + (decPlaces ? decSeparator + Math.abs(n - i).toFixed(decPlaces).slice(2) :""); }; |
它被重新格式化并从这里借用:https://stackoverflow.com/a/149099/751484
你必须提供你自己的货币代号(你用的是美元)。
这样称呼它(尽管请注意,参数默认为2、逗号和句点,因此如果您喜欢,则不需要提供任何参数):
1 2 | var myMoney=3543.75873; var formattedMoney = '$' + myMoney.formatMoney(2,',','.'); //"$3,543.76" |
这里已经有了一些很好的答案。这是另一个尝试,只是为了好玩:
1 2 3 4 5 6 | function formatDollar(num) { var p = num.toFixed(2).split("."); return"$" + p[0].split("").reverse().reduce(function(acc, num, i, orig) { return num=="-" ? acc : num + (i && !(i % 3) ?"," :"") + acc; },"") +"." + p[1]; } |
一些测试:
1 2 3 4 5 | formatDollar(45664544.23423) //"$45,664,544.23" formatDollar(45) //"$45.00" formatDollar(123) //"$123.00" formatDollar(7824) //"$7,824.00" formatDollar(1) //"$1.00" |
编辑:现在它也将处理负数
我想你想要的是
为什么没有人提出以下建议?
1 | (2500).toLocaleString("en-GB", {style:"currency", currency:"GBP", minimumFractionDigits: 2}) |
适用于大多数/部分浏览器:
https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_-objects/number/toLocaleString浏览器兼容性
numeral.js-一个JS库,可通过@adamwrapper轻松设置数字格式
1 | numeral(23456.789).format('$0,0.00'); // ="$23,456.79" |
我使用(来自微软的)图书馆全球化:
这是一个伟大的项目,本地化的数字,货币和日期,并让他们根据用户的地区自动格式化正确的方式!…尽管它应该是jquery扩展,但它目前是一个100%独立的库。我建议你们都试试看!:)
好吧,根据你说的,我用这个:
1 2 3 4 5 6 7 8 9 | var DecimalSeparator = Number("1.2").toLocaleString().substr(1,1); var AmountWithCommas = Amount.toLocaleString(); var arParts = String(AmountWithCommas).split(DecimalSeparator); var intPart = arParts[0]; var decPart = (arParts.length > 1 ? arParts[1] : ''); decPart = (decPart + '00').substr(0,2); return '£ ' + intPart + DecimalSeparator + decPart; |
我愿意接受改进建议(我不希望只包括Yui这样做:)我已经知道我应该检测"."而不是仅仅使用它作为小数点分隔符…
javascript数字格式化程序(以前在谷歌代码)
- 短、快、灵活但独立。
只有75行,包括MIT许可证信息、空白行和注释。 - 接受标准数字格式,如
#,##0.00 或带否定的-000.#### 。 - 接受任何国家格式,如
# ##0,00 、#,###.## 、#'###.## 或任何类型的非编号符号。 - 接受任何数字分组。
#,##,#0.000 或#,###0.## 均有效。 - 接受任何冗余/防误格式。
##,###,##.# 或0#,#00#.###0# 都可以。 - 自动编号舍入。
- 简单的界面,只需提供这样的掩码和值:
format("0.0000", 3.141592) 。 - 在掩码中包含前缀和后缀
(摘自自述文件)
+1.向乔纳森M提供原始方法。由于这显然是一个货币格式化程序,所以我继续向输出中添加了货币符号(默认为"$"),并添加了一个默认逗号作为千位分隔符。如果您实际上不需要货币符号(或千位分隔符),只需使用"(空字符串)作为参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Number.prototype.formatMoney = function(decPlaces, thouSeparator, decSeparator, currencySymbol) { // check the args and supply defaults: decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces; decSeparator = decSeparator == undefined ?"." : decSeparator; thouSeparator = thouSeparator == undefined ?"," : thouSeparator; currencySymbol = currencySymbol == undefined ?"$" : currencySymbol; var n = this, sign = n < 0 ?"-" :"", i = parseInt(n = Math.abs(+n || 0).toFixed(decPlaces)) +"", j = (j = i.length) > 3 ? j % 3 : 0; return sign + currencySymbol + (j ? i.substr(0, j) + thouSeparator :"") + i.substr(j).replace(/(\d{3})(?=\d)/g,"$1" + thouSeparator) + (decPlaces ? decSeparator + Math.abs(n - i).toFixed(decPlaces).slice(2) :""); }; |
有一个PHP函数"数字格式"的javascript端口。
我发现它非常有用,因为它易于使用,并且对PHP开发人员来说是可识别的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | function number_format (number, decimals, dec_point, thousands_sep) { var n = number, prec = decimals; var toFixedFix = function (n,prec) { var k = Math.pow(10,prec); return (Math.round(n*k)/k).toString(); }; n = !isFinite(+n) ? 0 : +n; prec = !isFinite(+prec) ? 0 : Math.abs(prec); var sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep; var dec = (typeof dec_point === 'undefined') ? '.' : dec_point; var s = (prec > 0) ? toFixedFix(n, prec) : toFixedFix(Math.round(n), prec); //fix for IE parseFloat(0.55).toFixed(0) = 0; var abs = toFixedFix(Math.abs(n), prec); var _, i; if (abs >= 1000) { _ = abs.split(/\D/); i = _[0].length % 3 || 3; _[0] = s.slice(0,i + (n < 0)) + _[0].slice(i).replace(/(\d{3})/g, sep+'$1'); s = _.join(dec); } else { s = s.replace('.', dec); } var decPos = s.indexOf(dec); if (prec >= 1 && decPos !== -1 && (s.length-decPos-1) < prec) { s += new Array(prec-(s.length-decPos-1)).join(0)+'0'; } else if (prec >= 1 && decPos === -1) { s += dec+new Array(prec).join(0)+'0'; } return s; } |
(注释块与原文不符,下面包含示例和信用证(如有到期)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | // Formats a number with grouped thousands // // version: 906.1806 // discuss at: http://phpjs.org/functions/number_format // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + bugfix by: Michael White (http://getsprink.com) // + bugfix by: Benjamin Lupton // + bugfix by: Allan Jensen (http://www.winternet.no) // + revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) // + bugfix by: Howard Yeend // + revised by: Luke Smith (http://lucassmith.name) // + bugfix by: Diogo Resende // + bugfix by: Rival // + input by: Kheang Hok Chin (http://www.distantia.ca/) // + improved by: davook // + improved by: Brett Zamir (http://brett-zamir.me) // + input by: Jay Klehr // + improved by: Brett Zamir (http://brett-zamir.me) // + input by: Amir Habibi (http://www.residence-mixte.com/) // + bugfix by: Brett Zamir (http://brett-zamir.me) // * example 1: number_format(1234.56); // * returns 1: '1,235' // * example 2: number_format(1234.56, 2, ',', ' '); // * returns 2: '1 234,56' // * example 3: number_format(1234.5678, 2, '.', ''); // * returns 3: '1234.57' // * example 4: number_format(67, 2, ',', '.'); // * returns 4: '67,00' // * example 5: number_format(1000); // * returns 5: '1,000' // * example 6: number_format(67.311, 2); // * returns 6: '67.31' // * example 7: number_format(1000.55, 1); // * returns 7: '1,000.6' // * example 8: number_format(67000, 5, ',', '.'); // * returns 8: '67.000,00000' // * example 9: number_format(0.9, 0); // * returns 9: '1' // * example 10: number_format('1.20', 2); // * returns 10: '1.20' // * example 11: number_format('1.20', 4); // * returns 11: '1.2000' // * example 12: number_format('1.2000', 3); // * returns 12: '1.200' |
使用正则表达式的较短方法(用于插入空格、逗号或点)?
1 2 3 4 5 6 | Number.prototype.toCurrencyString=function(){ return this.toFixed(2).replace(/(\d)(?=(\d{3})+\b)/g,'$1 '); } n=12345678.9; alert(n.toCurrencyString()); |
有一个内置的
1 2 | var num = new Number(349); document.write("$" + num.toFixed(2)); |
Patrick Desjardins的答案看起来不错,但我更喜欢简单的javascript。这是我刚写的一个函数,它接受一个数字并以货币格式返回(减去美元符号)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // Format numbers to two decimals with commas function formatDollar(num) { var p = num.toFixed(2).split("."); var chars = p[0].split("").reverse(); var newstr = ''; var count = 0; for (x in chars) { count++; if(count%3 == 1 && count != 1) { newstr = chars[x] + ',' + newstr; } else { newstr = chars[x] + newstr; } } return newstr +"." + p[1]; } |
我建议使用Google可视化API中的数字格式类。
你可以这样做:
1 2 3 4 5 6 | var formatter = new google.visualization.NumberFormat({ prefix: '$', pattern: '#,###,###.##' }); formatter.formatValue(1000000); // $ 1,000,000 |
希望能有所帮助。
没见过这个。它非常简洁易懂。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function moneyFormat(price, sign = '$') { const pieces = parseFloat(price).toFixed(2).split('') let ii = pieces.length - 3 while ((ii-=3) > 0) { pieces.splice(ii, 0, ',') } return sign + pieces.join('') } console.log( moneyFormat(100), moneyFormat(1000), moneyFormat(10000.00), moneyFormat(1000000000000000000) ) |
这是一个在最终输出中有更多选项的版本,允许以不同的地区格式格式化不同的货币。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | // higher order function that takes options then a price and will return the formatted price const makeMoneyFormatter = ({ sign = '$', delimiter = ',', decimal = '.', append = false, precision = 2, round = true, custom } = {}) => value => { const e = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000] value = round ? (Math.round(value * e[precision]) / e[precision]) : parseFloat(value) const pieces = value .toFixed(precision) .replace('.', decimal) .split('') let ii = pieces.length - (precision ? precision + 1 : 0) while ((ii-=3) > 0) { pieces.splice(ii, 0, delimiter) } if (typeof custom === 'function') { return custom({ sign, float: value, value: pieces.join('') }) } return append ? pieces.join('') + sign : sign + pieces.join('') } // create currency converters with the correct formatting options const formatDollar = makeMoneyFormatter() const formatPound = makeMoneyFormatter({ sign: '£', precision: 0 }) const formatEuro = makeMoneyFormatter({ sign: '€', delimiter: '.', decimal: ',', append: true }) const customFormat = makeMoneyFormatter({ round: false, custom: ({ value, float, sign }) => `SALE:$${value}USD` }) console.log( formatPound(1000), formatDollar(10000.0066), formatEuro(100000.001), customFormat(999999.555) ) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function CurrencyFormatted(amount) { var i = parseFloat(amount); if(isNaN(i)) { i = 0.00; } var minus = ''; if(i < 0) { minus = '-'; } i = Math.abs(i); i = parseInt((i + .005) * 100); i = i / 100; s = new String(i); if(s.indexOf('.') < 0) { s += '.00'; } if(s.indexOf('.') == (s.length - 2)) { s += '0'; } s = minus + s; return s; } |
来自Willmaster。
这可能有点晚了,但这里有一个方法,我刚刚为一个同事想出了一个方法,可以将一个支持区域设置的
在您需要使用它之前,在您头脑中的任何地方或任何必要的地方声明:
1 2 3 4 5 6 | Number.prototype.toCurrencyString = function(prefix, suffix) { if (typeof prefix === 'undefined') { prefix = '$'; } if (typeof suffix === 'undefined') { suffix = ''; } var _localeBug = new RegExp((1).toLocaleString().replace(/^1/, '').replace(/\./, '\\.') +"$"); return prefix + (~~this).toLocaleString().replace(_localeBug, '') + (this % 1).toFixed(2).toLocaleString().replace(/^[+-]?0+/,'') + suffix; } |
那你就完了!在任何需要将数字输出为货币的地方使用
1 2 3 4 | var MyNumber = 123456789.125; alert(MyNumber.toCurrencyString()); // alerts"$123,456,789.13" MyNumber = -123.567; alert(MyNumber.toCurrencyString()); // alerts"$-123.57" |
主要部分是插入千个分隔符,可以这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <script type="text/javascript"> function ins1000Sep(val){ val = val.split("."); val[0] = val[0].split("").reverse().join(""); val[0] = val[0].replace(/(\d{3})/g,"$1,"); val[0] = val[0].split("").reverse().join(""); val[0] = val[0].indexOf(",")==0?val[0].substring(1):val[0]; return val.join("."); } function rem1000Sep(val){ return val.replace(/,/g,""); } function formatNum(val){ val = Math.round(val*100)/100; val = (""+val).indexOf(".")>-1 ? val +"00" : val +".00"; var dec = val.indexOf("."); return dec == val.length-3 || dec == 0 ? val : val.substring(0,dec+3); } <button onclick="alert(ins1000Sep(formatNum(12313231)));"> |
这里有一些解决方案,都通过了测试套件,测试套件和基准包括在内,如果你想复制粘贴到测试,请尝试这个要点。
方法0(regexp)基于https://stackoverflow.com/a/14428340/1877620,但如果没有小数点,则修复。
1 2 3 4 5 6 7 8 9 10 11 | if (typeof Number.prototype.format === 'undefined') { Number.prototype.format = function (precision) { if (!isFinite(this)) { return this.toString(); } var a = this.toFixed(precision).split('.'); a[0] = a[0].replace(/\d(?=(\d{3})+$)/g, '$&,'); return a.join('.'); } } |
方法1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | if (typeof Number.prototype.format === 'undefined') { Number.prototype.format = function (precision) { if (!isFinite(this)) { return this.toString(); } var a = this.toFixed(precision).split('.'), // skip the '-' sign head = Number(this < 0); // skip the digits that's before the first thousands separator head += (a[0].length - head) % 3 || 3; a[0] = a[0].slice(0, head) + a[0].slice(head).replace(/\d{3}/g, ',$&'); return a.join('.'); }; } |
方法2(拆分为数组)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | if (typeof Number.prototype.format === 'undefined') { Number.prototype.format = function (precision) { if (!isFinite(this)) { return this.toString(); } var a = this.toFixed(precision).split('.'); a[0] = a[0] .split('').reverse().join('') .replace(/\d{3}(?=\d)/g, '$&,') .split('').reverse().join(''); return a.join('.'); }; } |
方法3(循环)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | if (typeof Number.prototype.format === 'undefined') { Number.prototype.format = function (precision) { if (!isFinite(this)) { return this.toString(); } var a = this.toFixed(precision).split(''); a.push('.'); var i = a.indexOf('.') - 3; while (i > 0 && a[i-1] !== '-') { a.splice(i, 0, ','); i -= 3; } a.pop(); return a.join(''); }; } |
使用实例
1 2 3 4 5 6 7 8 9 10 11 | console.log('======== Demo ========') console.log( (1234567).format(0), (1234.56).format(2), (-1234.56).format(0) ); var n = 0; for (var i=1; i<20; i++) { n = (n * 10) + (i % 10)/100; console.log(n.format(2), (-n).format(2)); } |
分离器
如果我们需要自定义千位分隔符或十进制分隔符,请使用
1 | 123456.78.format(2).replace(',', ' ').replace('.', ' '); |
测试套件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | function assertEqual(a, b) { if (a !== b) { throw a + ' !== ' + b; } } function test(format_function) { console.log(format_function); assertEqual('NaN', format_function.call(NaN, 0)) assertEqual('Infinity', format_function.call(Infinity, 0)) assertEqual('-Infinity', format_function.call(-Infinity, 0)) assertEqual('0', format_function.call(0, 0)) assertEqual('0.00', format_function.call(0, 2)) assertEqual('1', format_function.call(1, 0)) assertEqual('-1', format_function.call(-1, 0)) // decimal padding assertEqual('1.00', format_function.call(1, 2)) assertEqual('-1.00', format_function.call(-1, 2)) // decimal rounding assertEqual('0.12', format_function.call(0.123456, 2)) assertEqual('0.1235', format_function.call(0.123456, 4)) assertEqual('-0.12', format_function.call(-0.123456, 2)) assertEqual('-0.1235', format_function.call(-0.123456, 4)) // thousands separator assertEqual('1,234', format_function.call(1234.123456, 0)) assertEqual('12,345', format_function.call(12345.123456, 0)) assertEqual('123,456', format_function.call(123456.123456, 0)) assertEqual('1,234,567', format_function.call(1234567.123456, 0)) assertEqual('12,345,678', format_function.call(12345678.123456, 0)) assertEqual('123,456,789', format_function.call(123456789.123456, 0)) assertEqual('-1,234', format_function.call(-1234.123456, 0)) assertEqual('-12,345', format_function.call(-12345.123456, 0)) assertEqual('-123,456', format_function.call(-123456.123456, 0)) assertEqual('-1,234,567', format_function.call(-1234567.123456, 0)) assertEqual('-12,345,678', format_function.call(-12345678.123456, 0)) assertEqual('-123,456,789', format_function.call(-123456789.123456, 0)) // thousands separator and decimal assertEqual('1,234.12', format_function.call(1234.123456, 2)) assertEqual('12,345.12', format_function.call(12345.123456, 2)) assertEqual('123,456.12', format_function.call(123456.123456, 2)) assertEqual('1,234,567.12', format_function.call(1234567.123456, 2)) assertEqual('12,345,678.12', format_function.call(12345678.123456, 2)) assertEqual('123,456,789.12', format_function.call(123456789.123456, 2)) assertEqual('-1,234.12', format_function.call(-1234.123456, 2)) assertEqual('-12,345.12', format_function.call(-12345.123456, 2)) assertEqual('-123,456.12', format_function.call(-123456.123456, 2)) assertEqual('-1,234,567.12', format_function.call(-1234567.123456, 2)) assertEqual('-12,345,678.12', format_function.call(-12345678.123456, 2)) assertEqual('-123,456,789.12', format_function.call(-123456789.123456, 2)) } console.log('======== Testing ========'); test(Number.prototype.format); test(Number.prototype.format1); test(Number.prototype.format2); test(Number.prototype.format3); |
基准
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | function benchmark(f) { var start = new Date().getTime(); f(); return new Date().getTime() - start; } function benchmark_format(f) { console.log(f); time = benchmark(function () { for (var i = 0; i < 100000; i++) { f.call(123456789, 0); f.call(123456789, 2); } }); console.log(time.format(0) + 'ms'); } // if not using async, browser will stop responding while running. // this will create a new thread to benchmark async = []; function next() { setTimeout(function () { f = async.shift(); f && f(); next(); }, 10); } console.log('======== Benchmark ========'); async.push(function () { benchmark_format(Number.prototype.format); }); next(); |
通常,有多种方法可以做相同的事情,但我会避免使用
我也不建议扩展
我相信正则表达式是解决这个问题的最佳方法,下面是我的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /** * Converts number into currency format * @param {number} number Number that should be converted. * @param {string} [decimalSeparator] Decimal separator, defaults to '.'. * @param {string} [thousandsSeparator] Thousands separator, defaults to ','. * @param {int} [nDecimalDigits] Number of decimal digits, defaults to `2`. * @return {string} Formatted string (e.g. numberToCurrency(12345.67) returns '12,345.67') */ function numberToCurrency(number, decimalSeparator, thousandsSeparator, nDecimalDigits){ //default values decimalSeparator = decimalSeparator || '.'; thousandsSeparator = thousandsSeparator || ','; nDecimalDigits = nDecimalDigits == null? 2 : nDecimalDigits; var fixed = number.toFixed(nDecimalDigits), //limit/add decimal digits parts = new RegExp('^(-?\\d{1,3})((?:\\d{3})+)(\\.(\\d{'+ nDecimalDigits +'}))?$').exec( fixed ); //separate begin [$1], middle [$2] and decimal digits [$4] if(parts){ //number >= 1000 || number <= -1000 return parts[1] + parts[2].replace(/\d{3}/g, thousandsSeparator + '$&') + (parts[4] ? decimalSeparator + parts[4] : ''); }else{ return fixed.replace('.', decimalSeparator); } } |
2010/08/30编辑:增加了设置小数位数的选项。2011/08/23编辑:增加了将小数位数设置为零的选项。
我从:accounting.js找到这个。它非常简单,完全符合我的需要。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // Default usage: accounting.formatMoney(12345678); // $12,345,678.00 // European formatting (custom symbol and separators), can also use options object as second parameter: accounting.formatMoney(4999.99,"€", 2,".",","); // €4.999,99 // Negative values can be formatted nicely: accounting.formatMoney(-500000,"£", 0); // £ -500,000 // Simple `format` string allows control of symbol position (%v = value, %s = symbol): accounting.formatMoney(5318008, { symbol:"GBP", format:"%v %s" }); // 5,318,008.00 GBP // Euro currency symbol to the right accounting.formatMoney(5318008, {symbol:"€", precision: 2, thousand:".", decimal :",", format:"%v%s"}); // 1.008,00€ |
通过首先反转字符串和基本regexp来正确放置逗号的简单选项。
1 2 3 4 5 6 7 8 9 10 11 12 | String.prototype.reverse = function() { return this.split('').reverse().join(''); }; Number.prototype.toCurrency = function( round_decimal /*boolean*/ ) { // format decimal or round to nearest integer var n = this.toFixed( round_decimal ? 0 : 2 ); // convert to a string, add commas every 3 digits from left to right // by reversing string return (n + '').reverse().replace( /(\d{3})(?=\d)/g, '$1,' ).reverse(); }; |
Patrick Desjardins(前Daok)的例子对我很有用。如果有人感兴趣的话,我就去咖啡店。
1 2 3 4 5 6 7 8 9 10 | Number.prototype.toMoney = (decimals = 2, decimal_separator =".", thousands_separator =",") -> n = this c = if isNaN(decimals) then 2 else Math.abs decimals sign = if n < 0 then"-" else"" i = parseInt(n = Math.abs(n).toFixed(c)) + '' j = if (j = i.length) > 3 then j % 3 else 0 x = if j then i.substr(0, j) + thousands_separator else '' y = i.substr(j).replace(/(\d{3})(?=\d)/g,"$1" + thousands_separator) z = if c then decimal_separator + Math.abs(n - i).toFixed(c).slice(2) else '' sign + x + y + z |
YUI代码库使用以下格式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | format: function(nData, oConfig) { oConfig = oConfig || {}; if(!YAHOO.lang.isNumber(nData)) { nData *= 1; } if(YAHOO.lang.isNumber(nData)) { var sOutput = nData +""; var sDecimalSeparator = (oConfig.decimalSeparator) ? oConfig.decimalSeparator :"."; var nDotIndex; // Manage decimals if(YAHOO.lang.isNumber(oConfig.decimalPlaces)) { // Round to the correct decimal place var nDecimalPlaces = oConfig.decimalPlaces; var nDecimal = Math.pow(10, nDecimalPlaces); sOutput = Math.round(nData*nDecimal)/nDecimal +""; nDotIndex = sOutput.lastIndexOf("."); if(nDecimalPlaces > 0) { // Add the decimal separator if(nDotIndex < 0) { sOutput += sDecimalSeparator; nDotIndex = sOutput.length-1; } // Replace the"." else if(sDecimalSeparator !=="."){ sOutput = sOutput.replace(".",sDecimalSeparator); } // Add missing zeros while((sOutput.length - 1 - nDotIndex) < nDecimalPlaces) { sOutput +="0"; } } } // Add the thousands separator if(oConfig.thousandsSeparator) { var sThousandsSeparator = oConfig.thousandsSeparator; nDotIndex = sOutput.lastIndexOf(sDecimalSeparator); nDotIndex = (nDotIndex > -1) ? nDotIndex : sOutput.length; var sNewOutput = sOutput.substring(nDotIndex); var nCount = -1; for (var i=nDotIndex; i>0; i--) { nCount++; if ((nCount%3 === 0) && (i !== nDotIndex)) { sNewOutput = sThousandsSeparator + sNewOutput; } sNewOutput = sOutput.charAt(i-1) + sNewOutput; } sOutput = sNewOutput; } // Prepend prefix sOutput = (oConfig.prefix) ? oConfig.prefix + sOutput : sOutput; // Append suffix sOutput = (oConfig.suffix) ? sOutput + oConfig.suffix : sOutput; return sOutput; } // Still not a Number, just return unaltered else { return nData; } } |
它需要编辑,因为yui库是可配置的,比如用"."替换oconfig.decimalsparator。
55个答案显然是在寻求另一个答案。
1 2 3 4 5 6 7 8 9 10 11 12 13 | function centsToDollaString(x){ var cents = x +"" while(cents.length < 4){ cents ="0" + cents; } var dollars = cents.substr(0,cents.length - 2) var decimal = cents.substr(cents.length - 2, 2) while(dollars.length % 3 != 0){ dollars ="0" + dollars; } str = dollars.replace(/(\d{3})(?=\d)/g,"$1" +",").replace(/^0*(?=.)/,""); return"$" + str +"." + decimal; } |
@TGgagne是正确的。我下面的解决方案不好,因为浮动舍入。toLocaleString功能缺乏浏览器支持。我将留下以下评论,以备存档,以备不时之需。:)
https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_-objects/date/toLocaleString浏览器兼容性
(旧解决方案)使用Patrick Desjardins解决方案。
这是一个使用toLocaleString()的简单解决方案,自Javascript 1.0版起就得到了支持。此示例将货币指定为美元,但可以使用"英镑"而不是"美元"将其转换为英镑。
1 2 3 4 5 6 | var formatMoney = function (value) { // Convert the value to a floating point number in case it arrives as a string. var numeric = parseFloat(value); // Specify the local currency. return numeric.toLocaleString('USD', { style: 'currency', currency:"USD", minimumFractionDigits: 2, maximumFractionDigits: 2 }); } |
更多详情请参见https://marcoscaceres.github.io/jsi18n/本地化货币。
用于处理货币输出(包括负数)的函数。
样本输出:
5.23美元< BR>- 5.23美元
1 2 3 4 5 6 7 8 | function formatCurrency(total) { var neg = false; if(total < 0) { neg = true; total = Math.abs(total); } return (neg ?"-$" : '$') + parseFloat(total, 10).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g,"$1,").toString(); } |
http://code.google.com/p/javascript-number-formatter/:
- 短、快、灵活但独立。只有75行,包括MIT许可证信息、空白行和注释。
- 接受标准数字格式,如、0.00或带负号-000。。
- 接受任何国家格式,如或任何类型的非编号符号。
- 接受任何数字分组。#、、0.000或、0.均有效。
- 接受任何冗余/防误格式。##、、或0、00 0都还好。
- 自动编号舍入。
- 简单的界面,只需提供如下的掩码和值:格式("0.0000",3.141592)
更新这是我自己开发的用于最常见任务的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | var NumUtil = {}; /** Petty print 'num' wth exactly 'signif' digits. pp(123.45, 2) =="120" pp(0.012343, 3) =="0.0123" pp(1.2, 3) =="1.20" */ NumUtil.pp = function(num, signif) { if (typeof(num) !=="number") throw 'NumUtil.pp: num is not a number!'; if (isNaN(num)) throw 'NumUtil.pp: num is NaN!'; if (num < 1e-15 || num > 1e15) return num; var r = Math.log(num)/Math.LN10; var dot = Math.floor(r) - (signif-1); r = r - Math.floor(r) + (signif-1); r = Math.round(Math.exp(r * Math.LN10)).toString(); if (dot >= 0) { for (; dot > 0; dot -= 1) r +="0"; return r; } else if (-dot >= r.length) { var p ="0."; for (; -dot > r.length; dot += 1) { p +="0"; } return p+r; } else { return r.substring(0, r.length + dot) +"." + r.substring(r.length + dot); } } /** Append leading zeros up to 2 digits. */ NumUtil.align2 = function(v) { if (v < 10) return"0"+v; return""+v; } /** Append leading zeros up to 3 digits. */ NumUtil.align3 = function(v) { if (v < 10) return"00"+v; else if (v < 100) return"0"+v; return""+v; } NumUtil.integer = {}; /** Round to integer and group by 3 digits. */ NumUtil.integer.pp = function(num) { if (typeof(num) !=="number") { console.log("%s", new Error().stack); throw 'NumUtil.integer.pp: num is not a number!'; } if (isNaN(num)) throw 'NumUtil.integer.pp: num is NaN!'; if (num > 1e15) return num; if (num < 0) throw 'Negative num!'; num = Math.round(num); var group = num % 1000; var integ = Math.floor(num / 1000); if (integ === 0) { return group; } num = NumUtil.align3(group); while (true) { group = integ % 1000; integ = Math.floor(integ / 1000); if (integ === 0) return group +"" + num; num = NumUtil.align3(group) +"" + num; } return num; } NumUtil.currency = {}; /** Round to coins and group by 3 digits. */ NumUtil.currency.pp = function(amount) { if (typeof(amount) !=="number") throw 'NumUtil.currency.pp: amount is not a number!'; if (isNaN(amount)) throw 'NumUtil.currency.pp: amount is NaN!'; if (amount > 1e15) return amount; if (amount < 0) throw 'Negative amount!'; if (amount < 1e-2) return 0; var v = Math.round(amount*100); var integ = Math.floor(v / 100); var frac = NumUtil.align2(v % 100); var group = integ % 1000; integ = Math.floor(integ / 1000); if (integ === 0) { return group +"." + frac; } amount = NumUtil.align3(group); while (true) { group = integ % 1000; integ = Math.floor(integ / 1000); if (integ === 0) return group +"" + amount +"." + frac; amount = NumUtil.align3(group) +"" + amount; } return amount; } |
国际号码格式
1 2 3 | var number = 3500; alert(new Intl.NumberFormat().format(number)); // →"3,500" if in US English locale |
或phpjs.com/functions/number_格式
此答案符合以下标准:
- 不依赖于外部依赖项。
- 是否支持本地化。
- 有测试/证明。
- 使用简单和最佳的编码实践(没有复杂的regex,使用标准的编码模式)。
此代码基于其他答案的概念。如果这是一个问题的话,它的执行速度应该是最好的张贴在这里。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | var decimalCharacter = Number("1.1").toLocaleString().substr(1,1); var defaultCurrencyMarker ="$"; function formatCurrency(number, currencyMarker) { if (typeof number !="number") number = parseFloat(number, 10); // if NaN is passed in or comes from the parseFloat, set it to 0. if (isNaN(number)) number = 0; var sign = number < 0 ?"-" :""; number = Math.abs(number); // so our signage goes before the $ symbol. var integral = Math.floor(number); var formattedIntegral = integral.toLocaleString(); // IE returns"##.00" while others return"##" formattedIntegral = formattedIntegral.split(decimalCharacter)[0]; var decimal = Math.round((number - integral) * 100); return sign + (currencyMarker || defaultCurrencyMarker) + formattedIntegral + decimalCharacter + decimal.toString() + (decimal < 10 ?"0" :""); } |
这些测试只在美国本地机器上工作。这个决定是为了简单起见,因为这可能导致错误的输入(错误的自动本地化),从而导致错误的输出问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | var tests = [ // [ input, expected result ] [123123,"$123,123.00"], // no decimal [123123.123,"$123,123.12"], // decimal rounded down [123123.126,"$123,123.13"], // decimal rounded up [123123.4,"$123,123.40"], // single decimal ["123123","$123,123.00"], // repeat subset of the above using string input. ["123123.123","$123,123.12"], ["123123.126","$123,123.13"], [-123,"-$123.00"] // negatives ]; for (var testIndex=0; testIndex < tests.length; testIndex++) { var test = tests[testIndex]; var formatted = formatCurrency(test[0]); if (formatted == test[1]) { console.log("Test passed, "" + test[0] +"" resulted in "" + formatted +"""); } else { console.error("Test failed. Expected "" + test[1] +"", got "" + formatted +"""); } } |
https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/numberformat示例:使用区域设置
此示例显示本地化数字格式中的一些变体。要获取应用程序用户界面中使用的语言的格式,请确保使用locales参数指定该语言(可能还有一些回退语言):
var number = 123456.789;
// German uses comma as decimal separator and period for thousands
console.log(new Intl.NumberFormat('de-DE').format(number)); // →
123.456,789// Arabic in most Arabic speaking countries uses real Arabic digits
console.log(new Intl.NumberFormat('ar-EG').format(number)); // →
??????????// India uses thousands/lakh/crore separators console.log(new
Intl.NumberFormat('en-IN').format(number));
下面是将数字转换为货币格式的最佳方法:
1 2 3 4 5 | function toCurrency(amount){ return amount.replace(/(\d)(?=(\d\d\d)+(?!\d))/g,"$1,"); } // usage: toCurrency(3939920.3030); |
干杯!阿努伊
Jonathan M的代码对我来说很复杂,所以我重写了它,在FF V30上得到了30%,在Chrome V35速度提升上得到了60%(http://jsperf.com/number-formating2):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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; }; |
用途:
1 2 | var sum = 123456789.5698; var formatted = '$' + sum.formatNumber(2,',','.'); //"$123,456,789.57" |
1 2 3 | Number(value) .toFixed(2) .replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1,") |
符合原始要求的极简方法:
1 2 3 | function formatMoney(n) { return"$" + (Math.round(n * 100) / 100).toLocaleString(); } |
@丹尼尔·马格里奥拉:你说得对,上面是一个草率的,不完整的实施。以下是正确的实施:
1 2 3 4 | function formatMoney(n) { return"$" + n.toLocaleString().split(".")[0] +"." + n.toFixed(2).split(".")[1]; } |
下面是一个来自xmilley提供的代码的moooltools1.2实现…
1 2 3 4 5 6 7 8 9 10 11 12 | Number.implement('format', function(decPlaces, thouSeparator, decSeparator){ decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces; decSeparator = decSeparator === undefined ? '.' : decSeparator; thouSeparator = thouSeparator === undefined ? ',' : thouSeparator; var num = this, sign = num < 0 ? '-' : '', i = parseInt(num = Math.abs(+num || 0).toFixed(decPlaces)) + '', j = (j = i.length) > 3 ? j % 3 : 0; return sign + (j ? i.substr(0, j) + thouSeparator : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thouSeparator) + (decPlaces ? decSeparator + Math.abs(num - i).toFixed(decPlaces).slice(2) : ''); }); |
ToLocalString很好,但不能在所有浏览器上使用。我通常使用currencyformatter.js(https://osrec.github.io/currencyformatter.js/)。它非常轻,包含了所有的货币和语言环境定义。它还擅长格式化格式异常的货币,如印度卢比(按百万和千万卢比分组)。也没有依赖关系!
// Returns ? 25,34,234.00
// Returns 2.534.234,00 €
// Returns 2 534 234,00 €
在javascript中没有"formatNumber"的等价物。你可以自己写或者找到一个已经这样做的库。
这可能有效:
1 2 3 | function format_currency(v, number_of_decimals, decimal_separator, currency_sign){ return (isNaN(v)? v : currency_sign + parseInt(v||0).toLocaleString() + decimal_separator + (v*1).toFixed(number_of_decimals).slice(-number_of_decimals)); } |
没有循环,没有正则表达式,没有数组,没有奇异的条件。
雷杰普的诡计?
1 2 3 4 5 6 7 8 9 | Number.prototype.toMonetaryString=function(){var n=this.toFixed(2),m; // var=this.toFixed(2).replace(/\./,','); for comma separator // with a space for thousands separator while ((m=n.replace(/(\d)(\d\d\d)\b/g,'$1 $2'))!=n) n=m; return m; } String.prototype.fromMonetaryToNumber=function(s){ return this.replace(/[^\d-]+/g,'')/100; } |
因为为什么不添加另一个答案呢?我在很大程度上基于视觉的答案。
1 2 3 4 5 6 7 8 9 10 | function format (val) { val = (+val).toLocaleString(); val = (+val).toFixed(2); val +=""; return val.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g,"$1" + format.thousands); } (function (isUS) { format.decimal = isUS ?"." :","; format.thousands = isUS ?"," :"."; }(("" + (+(0.00).toLocaleString()).toFixed(2)).indexOf(".") > 0)); |
我用输入进行了测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | [ "" ,"1" ,"12" ,"123" ,"1234" ,"12345" ,"123456" ,"1234567" ,"12345678" ,"123456789" ,"1234567890" ,".12" ,"1.12" ,"12.12" ,"123.12" ,"1234.12" ,"12345.12" ,"123456.12" ,"1234567.12" ,"12345678.12" ,"123456789.12" ,"1234567890.12" ,"1234567890.123" ,"1234567890.125" ].forEach(function (item) { console.log(format(item)); }); |
得到这些结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 0.00 1.00 12.00 123.00 1,234.00 12,345.00 123,456.00 1,234,567.00 12,345,678.00 123,456,789.00 1,234,567,890.00 0.12 1.12 12.12 123.12 1,234.12 12,345.12 123,456.12 1,234,567.12 12,345,678.12 123,456,789.12 1,234,567,890.12 1,234,567,890.12 1,234,567,890.13 |
只是为了好玩。
我想要一个普通的javascript解决方案,自动返回小数部分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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"); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | String.prototype.toPrice = function () { var v; if (/^\d+(,\d+)$/.test(this)) v = this.replace(/,/, '.'); else if (/^\d+((,\d{3})*(\.\d+)?)?$/.test(this)) v = this.replace(/,/g,""); else if (/^\d+((.\d{3})*(,\d+)?)?$/.test(this)) v = this.replace(/\./g,"").replace(/,/,"."); var x = parseFloat(v).toFixed(2).toString().split("."), x1 = x[0], x2 = ((x.length == 2) ?"." + x[1] :".00"), exp = /^([0-9]+)(\d{3})/; while (exp.test(x1)) x1 = x1.replace(exp,"$1" +"," +"$2"); return x1 + x2; } alert("123123".toPrice()); //123,123.00 alert("123123,316".toPrice()); //123,123.32 alert("12,312,313.33213".toPrice()); //12,312,313.33 alert("123.312.321,32132".toPrice()); //123,312,321.32 |
我喜欢Vision最短的答案,除非我需要修改一个没有小数点的数字($123而不是$123.00),它不起作用,所以我需要破译javascript regex的晦涩语法,而不是快速复制/粘贴。
这是最初的解决方案
1 | n.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'); |
我会让它长一点:
1 2 3 | var re = /\d(?=(\d{3})+\.)/g; var subst = '$&,'; n.toFixed(2).replace(re, subst); |
此处的
这里的
当我们使用
所以在数字1234567.89中,数字1和4满足条件(1234567.89),并替换为"1"和"4",得到1234567.89。
如果我们根本不需要美元金额的小数点(即123美元而不是123美元),我们可以这样更改regex:
1 | var re2 = /\d(?=(\d{3})+$)/g; |
它依赖于行尾(
1 | n.toFixed(0).replace(/\d(?=(\d{3})+$)/g, '$&,'); |
这个表达式将给出
1 | 1234567.89 -> 1,234,567 |
另外,在上面的regex中,您也可以选择单词边界(
如果我误解了Regex处理的任何部分,请提前道歉。
我很难找到一个简单的库来处理日期和货币,所以我创建了我的:https://github.com/dericeira/slimformatter.js
简单的是:
1 | var number = slimFormatter.currency(2000.54); |
上面帕特里克流行答案的咖啡描述:
1 2 3 4 5 6 7 8 9 10 11 12 | Number::formatMoney = (decimalPlaces, decimalChar, thousandsChar) -> n = this c = decimalPlaces d = decimalChar t = thousandsChar c = (if isNaN(c = Math.abs(c)) then 2 else c) d = (if d is undefined then"." else d) t = (if t is undefined then"," else t) s = (if n < 0 then"-" else"") i = parseInt(n = Math.abs(+n or 0).toFixed(c)) +"" j = (if (j = i.length) > 3 then j % 3 else 0) s + (if j then i.substr(0, j) + t else"") + i.substr(j).replace(/(\d{3})(?=\d)/g,"$1" + t) + (if c then d + Math.abs(n - i).toFixed(c).slice(2) else"") |
许多答案都有有益的想法,但没有一个能满足我的需要。所以我运用了所有的想法并建立了这个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | 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>[.[cc lang="javascript"]]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, f.e.: var _f_octal= function( v_in,...){ //-------------------------------- if( typeof(fmt)!=="undefined"){ //...can be extended..., just add the char,f.e."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..., f.e.: 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样式的格式字符串定义,它应该是灵活的,但非常容易使用,我用以下方式定义了它:模式:
1 2 3 4 | %[<len>][.[cc lang="javascript"]]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欧元")。
除了灵活性之外,我还需要一个非常快速的处理表的解决方案。这意味着,在处理数千个单元格时,格式字符串的处理不能超过一次。我不接受类似"格式(值,fmt)"的调用,但必须分为两个步骤:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // 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) |
此外,为了提高性能,还将regexp封装在货币中;
第三,不接受类似"格式(值,fmt)"的调用,因为:虽然应该可以用不同的掩码格式化不同的对象集合(即列的单元格),但我不想在处理点处理格式字符串。此时,我只想使用格式,比如
for( var cell in cells){ do_something( cell.col.formatter(
cell.value)); }
什么格式-可能是在in i、每列的XML或其他某个地方定义的,但是分析和设置格式或处理国际化完全是在另一个地方处理的,在那里我想在不考虑性能问题的情况下将格式化程序分配给集合:
col.formatter = Format_Numb( _getFormatForColumn(...) );
第四,我需要一个"宽容"的解决方案,所以传递F.E.字符串而不是数字应该只返回字符串,但"空"应该返回空字符串。
(如果值太大,格式化"%4.2f"也不能剪切某些内容。)
最后但并非最不重要的一点——它应该可读且易于扩展,而不会对性能产生任何影响……例如,如果有人需要"八进制值",请参考带有"…可以扩展…"的行-我认为这应该是一个非常简单的任务。
我的主要精力放在表现上。每个"处理例程"(f.e.u money)都可以在这个线程或其他线程中封装优化或与其他想法交换,而不需要更改"准备例程"(分析格式字符串和创建函数),这些例程必须只处理一次,从这个意义上讲,并不像数千个nu的转换调用那样性能关键。梅伯斯
对于所有喜欢数字方法的人:
1 2 3 4 5 6 7 8 9 10 11 | 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(); |
虽然我测试了一些东西,但代码中可能有很多错误。所以这不是一个现成的模块,只是一个想法和一个像我这样的非JS专家的起点。代码中包含了大量stackoverflow文章中的许多和一些修改过的想法;抱歉,我不能引用所有这些想法,但要感谢所有专家。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function getMoney(A){ var a = new Number(A); var b = a.toFixed(2); //get 12345678.90 a = parseInt(a); // get 12345678 b = (b-a).toPrecision(2); //get 0.90 b = parseFloat(b).toFixed(2); //in case we get 0.0, we pad it out to 0.00 a = a.toLocaleString();//put in commas - IE also puts in .00, so we'll get 12,345,678.00 //if IE (our number ends in .00) if(a < 1 && a.lastIndexOf('.00') == (a.length - 3)) { a=a.substr(0, a.length-3); //delete the .00 } return a+b.substr(1);//remove the 0 from b, then return a + b = 12,345,678.90 } alert(getMoney(12345678.9)); |
这在FF和IE中有效
已经有了很好的答案。以下是简单的娱乐尝试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | function currencyFormat(no) { var ar = (+no).toFixed(2).split('.'); return [ numberFormat(ar[0]|0), '.', ar[1] ].join(''); } function numberFormat(no) { var str = no + ''; var ar = []; var i = str.length -1; while( i >= 0 ) { ar.push( (str[i-2]||'') + (str[i-1]|| '')+ (str[i]|| '')); i= i-3; } return ar.reverse().join(','); } |
运行一些示例
1 2 3 4 5 6 7 8 | console.log( currencyFormat(1), currencyFormat(1200), currencyFormat(123), currencyFormat(9870000), currencyFormat(12345), currencyFormat(123456.232) ) |
下面是一个简单的格式设置工具,在Vanilla JS中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | function numberFormatter (num) { console.log(num) var wholeAndDecimal = String(num.toFixed(2)).split("."); console.log(wholeAndDecimal) var reversedWholeNumber = Array.from(wholeAndDecimal[0]).reverse(); var formattedOutput = []; reversedWholeNumber.forEach( (digit, index) => { formattedOutput.push(digit); if ((index + 1) % 3 === 0 && index < reversedWholeNumber.length - 1) { formattedOutput.push(","); } }) formattedOutput = formattedOutput.reverse().join('') +"." + wholeAndDecimal[1]; return formattedOutput; } |
我喜欢简单:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function formatPriceUSD(price) { var strPrice = price.toFixed(2).toString(); var a = strPrice.split(''); if (price > 1000000000) a.splice(a.length - 12, 0, ','); if (price > 1000000) a.splice(a.length - 9, 0, ','); if (price > 1000) a.splice(a.length - 6, 0, ','); return '$' + a.join(""); } |
我想为此作出贡献:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function toMoney(amount) { neg = amount.charAt(0); amount= amount.replace(/\D/g, ''); amount= amount.replace(/\./g , ''); amount= amount.replace(/\-/g, ''); var numAmount = new Number(amount); amount= numAmount .toFixed(0).replace(/./g, function(c, i, a) { return i > 0 && c !=="," && (a.length - i) % 3 === 0 ?"." + c : c; }); if(neg == '-') return neg+amount; else return amount; } |
这允许您在一个文本框中转换数字,在该文本框中,您只需要supose来放置数字(考虑此方案)。
这将清除一个文本框,其中只包含数字,即使您粘贴一个包含数字、字母或任何字符的字符串。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | <html> <head> <script language=="Javascript"> function isNumber(evt) { var theEvent = evt || window.event; var key = theEvent.keyCode || theEvent.which; key = String.fromCharCode(key); if (key.length == 0) return; var regex = /^[0-9\-\b]+$/; if (!regex.test(key)) { theEvent.returnValue = false; if (theEvent.preventDefault) theEvent.preventDefault(); } } function toMoney(amount) { neg = amount.charAt(0); amount= amount.replace(/\D/g, ''); amount= amount.replace(/\./g , ''); amount= amount.replace(/\-/g, ''); var numAmount = new Number(amount); amount= numAmount .toFixed(0).replace(/./g, function(c, i, a) { return i > 0 && c !=="," && (a.length - i) % 3 === 0 ?"." + c : c; }); if(neg == '-') return neg+amount; else return amount; } function clearText(inTxt, newTxt, outTxt) { inTxt = inTxt.trim(); newTxt = newTxt.trim(); if(inTxt == '' || inTxt == newTxt) return outTxt; return inTxt; } function fillText(inTxt, outTxt) { inTxt = inTxt.trim(); if(inTxt != '') outTxt = inTxt; return outTxt; } </head> <body> $ <input name=reca2 id=reca2 type=text value="0" onFocus="this.value = clearText(this.value, '0', '');" onblur="this.value = fillText(this.value, '0'); this.value = toMoney(this.value);" onKeyPress="isNumber(event);" style="width:80px;" /> </body> </html> |
这是我的…
1 2 3 4 5 6 7 8 9 10 11 | function thousandCommas(num) { num = num.toString().split('.'); var ints = num[0].split('').reverse(); for (var out=[],len=ints.length,i=0; i < len; i++) { if (i > 0 && (i % 3) === 0) out.push(','); out.push(ints[i]); } out = out.reverse() && out.join(''); if (num.length === 2) out += '.' + num[1]; return out; } |
因为每个问题都需要一线解决方案:
1 | Number.prototype.formatCurrency = function() { return this.toFixed(2).toString().split(/[-.]/).reverse().reduceRight(function (t, c, i) { return (i == 2) ? '-' + t : (i == 1) ? t + c.replace(/(\d)(?=(\d{3})+$)/g, '$1,') : t + '.' + c; }, '$'); } |
对于不同的区域设置,这很容易更改,只需将"$1"更改为"$1."和".to"、"to"、"to swap"和。在数字中,货币符号可以通过更改末尾的"$"来更改。
或者,如果您有ES6,您可以用默认值声明函数:
1 2 3 4 5 6 7 8 | Number.prototype.formatCurrency = function(thou = ',', dec = '.', sym = '$') { return this.toFixed(2).toString().split(/[-.]/).reverse().reduceRight(function (t, c, i) { return (i == 2) ? '-' + t : (i == 1) ? t + c.replace(/(\d)(?=(\d{3})+$)/g, '$1' + thou) : t + dec + c; }, sym); } console.log((4215.57).formatCurrency()) $4,215.57 console.log((4216635.57).formatCurrency('.', ',')) $4.216.635,57 console.log((4216635.57).formatCurrency('.', ',',"\u20AC")) €4.216.635,57 |
哦,它也适用于负数:
1 2 3 4 | console.log((-6635.574).formatCurrency('.', ',',"\u20AC")) -€6.635,57 console.log((-1066.507).formatCurrency()) -$1,066.51 |
当然,你不必有货币符号
1 2 3 4 5 6 | console.log((1234.586).formatCurrency(',','.','')) 1,234.59 console.log((-7890123.456).formatCurrency(',','.','')) -7,890,123.46 console.log((1237890.456).formatCurrency('.',',','')) 1.237.890,46 |
下面是使用regexp和replace的快速方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function formatCurrency( number, dp, ts ) { var num = parseFloat( number ); //convert to float var pw; //for IE dp = parseInt( dp, 10 ); //decimal point dp = isNaN( dp ) ? 2 : dp; //default 2 decimal point ts = ts || ','; //thousands separator return num != number ? false : //return false for NaN ( ( 0.9 ).toFixed( 0 ) == '1' ? //for cater IE toFixed bug num.toFixed( dp ) : //format to fix n decimal point with round up ( Math.round( num * ( pw = Math.pow( 10, dp ) || 1 ) ) / pw ).toFixed( dp ) //for fix ie toFixed bug on round up value like 0.9 in toFixed ).replace( /^(-?\d{1,3})((\d{3})*)(\.\d+)?$/, function( all, first, subsequence, dmp, dec ) { //separate string into different parts return ( first || '' ) + subsequence.replace( /(\d{3})/g, ts + '$1' ) + ( dec || '' ); //add thousands seperator and re-join all parts } ); } |