How to print a number with commas as thousands separators in JavaScript
我正试图用带逗号的数千分隔符的javascript打印一个整数。例如,我想将数字1234567显示为"1234567"。我该怎么做呢?
我是这样做的:
1 2 3 4 5 6 7 | function numberWithCommas(x) { x = x.toString(); var pattern = /(-?\d+)(\d{3})/; while (pattern.test(x)) x = x.replace(pattern,"$1,$2"); return x; } |
有更简单或更优雅的方法吗?如果它也能和float一起工作,那就更好了,但这不是必需的。它不需要特定于区域设置来决定句点和逗号。
我使用了克里的回答,但简化了它,因为我只是为了我的特定目的寻找简单的东西。以下是我所做的:
1 2 3 | function numberWithCommas(x) { return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g,","); } |
这就是你真正需要知道的。
@NeilsBom问Regex如何工作。我的解释有点长。它不符合评论,我也不知道把它放在哪里,所以我在这里做。如果有人对把它放在哪里有其他建议,请告诉我。
regex使用两个lookahead断言:一个正数查找字符串中在其后面一行中有3位数的倍数的任何点,另一个负数断言确保该点只有3位数的倍数。替换表达式在此处放置逗号。
例如,如果传递"123456789.01",则肯定断言将匹配7左侧的每个点(因为"789"是3位数的倍数,"678"是3位数的倍数,"567"等)。否定断言检查3位数的倍数后面没有任何位数。"789"后面有一个句点,所以它正好是3位数的倍数,所以这里有一个逗号。"678是3位数的倍数,但后面有一个"9",所以这3位数是4位数的一组的一部分,逗号不在这组数字后面。类似于"567"。456789"是6位数字,是3的倍数,因此前面加逗号。"345678是3的倍数,但后面有一个"9",所以没有逗号。等等。""防止regex在字符串的开头加逗号。
@Neu-rah提到,如果小数点后的数字超过3位,则此函数会在不希望出现的位置添加逗号。如果这是一个问题,您可以使用此函数:
1 2 3 4 5 | function numberWithCommas(x) { var parts = x.toString().split("."); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g,","); return parts.join("."); } |
我很惊讶没人提到数字。原型。ToLocalString。它是在Javascript1.5中实现的(这是在1999年引入的),所以它基本上支持跨主要浏览器。
1 2 3 | var n = 34523453.345 n.toLocaleString() "34,523,453.345" |
从v0.12起,它还通过包含intl在node.js中工作
注意这个函数返回的字符串不是数字
如果您想要不同的东西,numeral.js可能会很有趣。
1 | var number = 1234567890; // Example number to be converted |
?请注意,javascript的最大整数值为9007199254740991
TelaCaleSouth:
1 2 3 4 5 | number.toLocaleString(); //"1,234,567,890" // A more complex example: var number2 = 1234.56789; // floating point example number2.toLocaleString(undefined, {maximumFractionDigits:2}) //"1,234.57" |
数字格式(不支持Safari):
1 2 | var nf = new Intl.NumberFormat(); nf.format(number); //"1,234,567,890" |
根据我所检查的(至少是火狐),它们在性能方面或多或少是相同的。
我建议使用phpjs.org的数字格式()。
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 | function number_format(number, decimals, dec_point, thousands_sep) { // http://kevin.vanzonneveld.net // + 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) // + improved by: Theriault // + improved by: Drew Noakes // * 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' var n = !isFinite(+number) ? 0 : +number, prec = !isFinite(+decimals) ? 0 : Math.abs(decimals), sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, dec = (typeof dec_point === 'undefined') ? '.' : dec_point, toFixedFix = function (n, prec) { // Fix for IE parseFloat(0.55).toFixed(0) = 0; var k = Math.pow(10, prec); return Math.round(n * k) / k; }, s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.'); if (s[0].length > 3) { s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, 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); } |
更新02/13/14
人们一直在报告这并不像预期的那样工作,所以我做了一个包含自动测试的JS小提琴。
更新日期:2017年11月26日
下面是一个稍微修改了输出的堆栈片段:
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 | function number_format(number, decimals, dec_point, thousands_sep) { // http://kevin.vanzonneveld.net // + 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) // + improved by: Theriault // + improved by: Drew Noakes // * 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' var n = !isFinite(+number) ? 0 : +number, prec = !isFinite(+decimals) ? 0 : Math.abs(decimals), sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, dec = (typeof dec_point === 'undefined') ? '.' : dec_point, toFixedFix = function (n, prec) { // Fix for IE parseFloat(0.55).toFixed(0) = 0; var k = Math.pow(10, prec); return Math.round(n * k) / k; }, s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.'); if (s[0].length > 3) { s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, 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); } var exampleNumber = 1; function test(expected, number, decimals, dec_point, thousands_sep) { var actual = number_format(number, decimals, dec_point, thousands_sep); console.log( 'Test case ' + exampleNumber + ': ' + '(decimals: ' + (typeof decimals === 'undefined' ? '(default)' : decimals) + ', dec_point:"' + (typeof dec_point === 'undefined' ? '(default)' : dec_point) + '"' + ', thousands_sep:"' + (typeof thousands_sep === 'undefined' ? '(default)' : thousands_sep) + '")' ); console.log(' => ' + (actual === expected ? 'Passed' : 'FAILED') + ', got"' + actual + '", expected"' + expected + '".'); exampleNumber++; } test('1,235', 1234.56); test('1 234,56', 1234.56, 2, ',', ' '); test('1234.57', 1234.5678, 2, '.', ''); test('67,00', 67, 2, ',', '.'); test('1,000', 1000); test('67.31', 67.311, 2); test('1,000.6', 1000.55, 1); test('67.000,00000', 67000, 5, ',', '.'); test('1', 0.9, 0); test('1.20', '1.20', 2); test('1.2000', '1.20', 4); test('1.200', '1.2000', 3); |
1 2 3 | .as-console-wrapper { max-height: 100% !important; } |
这是@mikez302答案的变体,但经过修改以支持带小数的数字(根据@neu rah的反馈,数字带逗号(12345.6789)->"12345.6789"而不是"12345.6789"
1 2 3 4 | function numberWithCommas(n) { var parts=n.toString().split("."); return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g,",") + (parts[1] ?"." + parts[1] :""); } |
1 2 3 4 5 6 7 | function formatNumber (num) { return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1,") } print(formatNumber(2665)); // 2,665 print(formatNumber(102665)); // 102,665 print(formatNumber(111102665)); // 111,102,665 |
使用正则表达式
1 2 3 4 5 6 7 | function toCommas(value) { return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g,","); } console.log(toCommas(123456789)); // 123,456,789 console.log(toCommas(1234567890)); // 1,234,567,890 console.log(toCommas(1234)); // 1,234 |
使用ToLocaleString()。
1 2 3 4 5 6 7 8 9 10 11 12 13 | var number = 123456.789; // request a currency format console.log(number.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' })); // → 123.456,79 € // the Japanese yen doesn't use a minor unit console.log(number.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' })) // → ¥123,457 // limit to three significant digits console.log(number.toLocaleString('en-IN', { maximumSignificantDigits: 3 })); // → 1,23,000 |
引用mdn:number.prototype.toLocaleString()
使用intl.numberFormat()。
1 2 3 4 5 6 7 8 9 10 11 12 13 | var number = 123456.789; console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(number)); // expected output:"123.456,79 €" // the Japanese yen doesn't use a minor unit console.log(new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(number)); // expected output:"¥123,457" // limit to three significant digits console.log(new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(number)); // expected output:"1,23,000" |
参考国际号码格式
在这里演示
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 | <script type="text/javascript"> // Using Regular expression function toCommas(value) { return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g,","); } function commas() { var num1 = document.myform.number1.value; // Using Regular expression document.getElementById('result1').value = toCommas(parseInt(num1)); // Using toLocaleString() document.getElementById('result2').value = parseInt(num1).toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' }); // Using Intl.NumberFormat() document.getElementById('result3').value = new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(num1); } <FORM NAME="myform"> <INPUT TYPE="text" NAME="number1" VALUE="123456789"> <INPUT TYPE="button" NAME="button" Value="=>" onClick="commas()"> Using Regular expression <INPUT TYPE="text" ID="result1" NAME="result1" VALUE=""> Using toLocaleString() <INPUT TYPE="text" ID="result2" NAME="result2" VALUE=""> Using Intl.NumberFormat() <INPUT TYPE="text" ID="result3" NAME="result3" VALUE=""> </FORM> |
性能
网址:http://jsben.ch/sifrd
国际号码格式
本地JS函数。支持IE11、EDGE、最新Safari、Chrome、Firefox、Opera、iOS版Safari和Android版Chrome。
1 2 3 4 | var number = 3500; console.log(new Intl.NumberFormat().format(number)); // → '3,500' if in US English locale |
感谢大家的回复。我建立了一些答案来制定一个更"一刀切"的解决方案。
第一个片段向数字原型添加了一个模仿php的
1 2 3 4 5 6 7 8 9 | Number.prototype.numberFormat = function(decimals, dec_point, thousands_sep) { dec_point = typeof dec_point !== 'undefined' ? dec_point : '.'; thousands_sep = typeof thousands_sep !== 'undefined' ? thousands_sep : ','; var parts = this.toFixed(decimals).split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousands_sep); return parts.join(dec_point); } |
您可以如下使用:
1 2 3 | var foo = 5000; console.log(foo.numberFormat(2)); // us format: 5,000.00 console.log(foo.numberFormat(2, ',', '.')); // european format: 5.000,00 |
我发现我经常需要为数学运算返回数字,但parsefloat将5000转换为5,只需取第一个整数值序列。所以我创建了自己的float转换函数并将其添加到字符串原型中。
1 2 3 4 5 6 7 8 9 10 | String.prototype.getFloat = function(dec_point, thousands_sep) { dec_point = typeof dec_point !== 'undefined' ? dec_point : '.'; thousands_sep = typeof thousands_sep !== 'undefined' ? thousands_sep : ','; var parts = this.split(dec_point); var re = new RegExp("[" + thousands_sep +"]"); parts[0] = parts[0].replace(re, ''); return parseFloat(parts.join(dec_point)); } |
现在您可以使用以下两种功能:
1 2 3 4 5 | var foo = 5000; var fooString = foo.numberFormat(2); // The string 5,000.00 var fooFloat = fooString.getFloat(); // The number 5000; console.log((fooString.getFloat() + 1).numberFormat(2)); // The string 5,001.00 |
我认为这是最短的正则表达式:
1 2 3 | /\B(?=(\d{3})+\b)/g "123456".replace(/\B(?=(\d{3})+\b)/g,",") |
我在一些数字上查了一下,结果成功了。
如果所有浏览器(Safari)都是本地提供的,那么
我查了所有其他的答案,但似乎没有人多填。这里是一个POC,它实际上是前两个答案的组合;如果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | var putThousandsSeparators; putThousandsSeparators = function(value, sep) { if (sep == null) { sep = ','; } // check if it needs formatting if (value.toString() === value.toLocaleString()) { // split decimals var parts = value.toString().split('.') // format whole numbers parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, sep); // put them back together value = parts[1] ? parts.join('.') : parts[0]; } else { value = value.toLocaleString(); } return value; }; alert(putThousandsSeparators(1234567.890)); |
可以使用浏览器的
1 2 | Intl.NumberFormat().format(1234); // returns"1,234" if the user's locale is en_US, for example |
有关更多信息,请参阅MDN关于数字格式的文章,您可以指定区域设置行为或用户的默认值。这有点简单,因为它尊重本地差异;许多国家使用句点分隔数字,而逗号表示小数。
Intl.NumberFormat还没有在所有浏览器中都可用,但它可以在最新的Chrome、Opera等浏览器中使用。火狐的下一个版本应该支持它。WebKit似乎没有实现的时间表。
您可以使用此过程设置所需的货币格式。
1 2 3 4 5 6 7 | var nf = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 2, maximumFractionDigits: 2 }); nf.format(123456.789); // ‘$123,456.79’ |
有关详细信息,您可以访问此链接。
https://www.justinmcandress.com/post/formatting-currency-in-javascript/
如果您要处理大量的货币值和格式设置,那么可能需要添加处理大量边缘案例和本地化的Tiny Accounting.js:
1 2 3 4 5 6 7 8 9 10 11 | // Default usage: accounting.formatMoney(12345678); // $12,345,678.00 // European formatting (custom symbol and separators), could also use options object as second param: accounting.formatMoney(4999.99,"€", 2,".",","); // €4.999,99 // Negative values are formatted nicely, too: 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 |
下面的代码使用char扫描,因此没有regex。
1 2 3 4 5 6 | function commafy( num){ var parts = (''+(num<0?-num:num)).split("."), s=parts[0], L, i=L= s.length, o=''; while(i--){ o = (i===0?'':((L-i)%3?'':',')) +s.charAt(i) +o } return (num<0?'-':'') + o + (parts[1] ? '.' + parts[1] : ''); } |
它显示了良好的性能:http://jspef.com/number-formatting-with-commas/5
2015.4.26:在num<0时解决问题的小修复。参见https://jsfiddle.net/runsun/p5tqqvs3/
下面是一个简单的函数,它为千位分隔符插入逗号。它使用数组函数而不是regex。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /** * Format a number as a string with commas separating the thousands. * @param num - The number to be formatted (e.g. 10000) * @return A string representing the formatted number (e.g."10,000") */ var formatNumber = function(num) { var array = num.toString().split(''); var index = -3; while (array.length + index > 0) { array.splice(index, 0, ','); // Decrement by 4 since we just added another unit to the array. index -= 4; } return array.join(''); }; |
带示例的codesandbox链接:https://codesandbox.io/s/p38k63w0vq
我写这篇文章之前,在这篇文章上跌跌撞撞。没有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 | $(function(){ function insertCommas(s) { // get stuff before the dot var d = s.indexOf('.'); var s2 = d === -1 ? s : s.slice(0, d); // insert commas every 3 digits from the right for (var i = s2.length - 3; i > 0; i -= 3) s2 = s2.slice(0, i) + ',' + s2.slice(i); // append fractional part if (d !== -1) s2 += s.slice(d); return s2; } $('#theDudeAbides').text( insertCommas('1234567.89012' ) ); }); |
1 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> |
对我来说,最好的答案是像一些会员说的那样使用摇头丸。如果要包含"$"符号,只需添加languaje和type选项。下面是将数字格式化为墨西哥比索的示例
1 2 | var n = 1234567.22 alert(n.toLocaleString("es-MX",{style:"currency", currency:"MXN"})) |
捷径
1 | 1234567.22.toLocaleString("es-MX",{style:"currency", currency:"MXN"}) |
让我试着改进Ukolka的答案,也许可以帮助其他人节省一些时间。
使用Mulal.js。
1 | document.body.textContent = numeral(1234567).format('0,0'); |
1 | <script src="//cdnjs.cloudflare.com/ajax/libs/numeral.js/1.4.5/numeral.min.js"> |
您应该使用number.prototype.toLocaleString&40;&41;仅当它的浏览器兼容性不是问题时。
1 2 3 4 5 6 7 8 | var formatNumber = function (number) { var splitNum; number = Math.abs(number); number = number.toFixed(2); splitNum = number.split('.'); splitNum[0] = splitNum[0].replace(/\B(?=(\d{3})+(?!\d))/g,","); return splitNum.join("."); } |
编辑:该函数只能使用正数。对于Expple:
1 2 | var number = -123123231232; formatNumber(number) |
输出:"123123231232"
但要回答上述问题,
1 2 | var number = 123123231232; number.toLocaleString() |
输出:"123123231232"
加油!
我认为这个函数将处理与这个问题相关的所有问题。
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 | function commaFormat(inputString) { inputString = inputString.toString(); var decimalPart =""; if (inputString.indexOf('.') != -1) { //alert("decimal number"); inputString = inputString.split("."); decimalPart ="." + inputString[1]; inputString = inputString[0]; //alert(inputString); //alert(decimalPart); } var outputString =""; var count = 0; for (var i = inputString.length - 1; i >= 0 && inputString.charAt(i) != '-'; i--) { //alert("inside for" + inputString.charAt(i) +"and count=" + count +" and outputString=" + outputString); if (count == 3) { outputString +=","; count = 0; } outputString += inputString.charAt(i); count++; } if (inputString.charAt(0) == '-') { outputString +="-"; } //alert(outputString); //alert(outputString.split("").reverse().join("")); return outputString.split("").reverse().join("") + decimalPart; } |
已经有很多好的答案了。这是另一个,只是为了好玩:
1 2 3 4 5 6 7 8 9 10 | function format(num, fix) { var p = num.toFixed(fix).split("."); return p[0].split("").reduceRight(function(acc, num, i, orig) { if ("-" === num && 0 === i) { return num + acc; } var pos = orig.length - i - 1 return num + (pos && !(pos % 3) ?"," :"") + acc; },"") + (p[1] ?"." + p[1] :""); } |
一些例子:
1 2 3 4 | format(77.03453, 2); //"77.03" format(78436589374); //"78,436,589,374" format(784, 4); //"784.0000" format(-123456); //"-123,456" |
使用此代码处理印度的货币格式。可以更改国家代码以处理其他国家货币。
1 2 3 4 5 6 7 8 | let amount =350256.95 var formatter = new Intl.NumberFormat('en-IN', { minimumFractionDigits: 2, }); // Use it. formatter.format(amount); |
输出:
1 | 3,50,256.95 |
我认为你的解决方案是我见过的较短的方案之一。我不认为有任何标准的javascript函数可以完成这类工作,所以您可能是自己完成的。
我检查了CSS3规范,看看是否有可能在CSS中实现这一点,但是除非你想要它自己的
我确实在谷歌代码上发现了一个有前途的项目:灵活的JS格式。我没有使用它,但它看起来相当灵活,并且有使用JSUnit的单元测试。开发人员也有很多关于这个主题的文章(尽管很旧)。
一定要考虑国际用户:许多国家使用空格作为分隔符,并使用逗号将小数与数字的整数部分分隔开。
我在AKI143S的溶液中加入了TOFIXED。此解决方案使用点作为千位分隔符,使用逗号作为精度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function formatNumber( num, fixed ) { var decimalPart; var array = Math.floor(num).toString().split(''); var index = -3; while ( array.length + index > 0 ) { array.splice( index, 0, '.' ); index -= 4; } if(fixed > 0){ decimalPart = num.toFixed(fixed).split(".")[1]; return array.join('') +"," + decimalPart; } return array.join(''); }; |
实例;
1 2 3 | formatNumber(17347, 0) = 17.347 formatNumber(17347, 3) = 17.347,000 formatNumber(1234563.4545, 3) = 1.234.563,454 |
@user1437663的解决方案非常好。
真正理解解决方案的人正在准备理解复杂的正则表达式。
一个小的改进使它更易读:
1 2 3 4 | function numberWithCommas(x) { var parts = x.toString().split("."); return parts[0].replace(/\B(?=(\d{3})+(?=$))/g,",") + (parts[1] ?"." + parts[1] :""); } |
模式以开头,以避免在单词开头使用逗号。有趣的是,模式返回为空,因为没有前进"光标"(同样适用于$)。
OB后面跟着一个不太知名的资源,但它是Perl正则表达式的一个强大功能。
1 | Pattern1 (? = (Pattern2) ). |
神奇的是,圆括号(pattern2)中的内容是遵循上一个模式(pattern1)的模式,但不前进光标,也不是返回的模式的一部分。这是一种未来的模式。当有人向前看,但实际上不走路时,这是相似的!
在这种情况下,模式2是
1 | \d{3})+(?=$) |
它表示3位数字(一次或多次),后跟字符串结尾($)
最后,replace方法将找到的模式(空字符串)的所有出现处更改为逗号。只有在剩余部分是3位数的倍数的情况下才会发生这种情况。(例如,未来光标到达原点的末端)。
我发现了一种适用于各种情况的方法。代码沙盒示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | function commas(n) { if (n < 1000) { return n + '' } else { // Convert to string. n += '' // Skip scientific notation. if (n.indexOf('e') !== -1) { return n } // Support fractions. let i = n.indexOf('.') let f = i == -1 ? '' : n.slice(i) if (f) n = n.slice(0, i) // Add commas. i = n.length n = n.split('') while (i > 3) n.splice((i -= 3), 0, ',') return n.join('') + f } } |
这就像诺亚·弗雷塔斯的答案,但支持分数和科学记数法。
如果不考虑性能,我认为
编辑:这里有一个代码沙盒和一些示例:https://codesandbox.io/s/zmvxjpj6x
在这里找不到一个现代和全面的解决方案之后,我编写了一个箭头函数(不带regex)来解决格式化问题,它允许调用者为欧洲和世界其他地区提供小数位数、句点和千位分隔符。
Examples:
1
2
3 numberFormatter(1234567890.123456) => 1,234,567,890
numberFormatter(1234567890.123456, 4) => 1,234,567,890.1235
numberFormatter(1234567890.123456, 4, '.', ',') => 1.234.567.890,1235 Europe
以下是用ES6(现代语法)编写的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | const numberFormatter = (number, fractionDigits = 0, thousandSeperator = ',', fractionSeperator = '.') => { if (number!==0 && !number || !Number.isFinite(number)) return number const frDigits = Number.isFinite(fractionDigits)? Math.min(Math.max(fractionDigits, 0), 7) : 0 const num = number.toFixed(frDigits).toString() const parts = num.split('.') let digits = parts[0].split('').reverse() let sign = '' if (num < 0) {sign = digits.pop()} let final = [] let pos = 0 while (digits.length > 1) { final.push(digits.shift()) pos++ if (pos % 3 === 0) {final.push(thousandSeperator)} } final.push(digits.shift()) return `${sign}${final.reverse().join('')}${frDigits > 0 ? fractionSeperator : ''}${frDigits > 0 && parts[1] ? parts[1] : ''}` } |
它已被测试为负输入,不良输入和NAN情况。如果输入是NaN,那么它只返回它。
这里有一个支持int&decimal的单行函数。我留下了一些代码来将数字转换成字符串。
1 2 3 | function numberWithCommas(x) { return (x=x+'').replace(new RegExp('\\B(?=(\\d{3})+'+(~x.indexOf('.')?'\\.':'$')+')','g'),','); } |
这是我的尝试:
编辑:以小数形式添加
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 | function splitMille(n, separator = ',') { // Cast to string let num = (n + '') // Test for and get any decimals (the later operations won't support them) let decimals = '' if (/\./.test(num)) { // This regex grabs the decimal point as well as the decimal numbers decimals = num.replace(/^.*(\..*)$/, '$1') } // Remove decimals from the number string num = num.replace(decimals, '') // Reverse the number string through Array functions .split('').reverse().join('') // Split into groups of 1-3 characters (with optional supported character"-" for negative numbers) .match(/[0-9]{1,3}-?/g) // Add in the mille separator character and reverse back .join(separator).split('').reverse().join('') // Put the decimals back and output the formatted number return `${num}${decimals}` } let testA = splitMille(1234) let testB = splitMille(-1234) let testC = splitMille(123456.789) let testD = splitMille(9007199254740991) let testE = splitMille(1000.0001) console.log('Results! \tA: %s \tB: %s \tC: %s \tD: %s \tE: %s', testA, testB, testC, testD, testE) |
另一种方法,支持小数、不同分隔符和负数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | var number_format = function(number, decimal_pos, decimal_sep, thousand_sep) { var ts = ( thousand_sep == null ? ',' : thousand_sep ) , ds = ( decimal_sep == null ? '.' : decimal_sep ) , dp = ( decimal_pos == null ? 2 : decimal_pos ) , n = Math.abs(Math.ceil(number)).toString() , i = n.length % 3 , f = n.substr(0, i) ; if(number < 0) f = '-' + f; for(;i<n.length;i+=3) { if(i!=0) f+=ts; f+=n.substr(i,3); } if(dp > 0) f += ds + number.toFixed(dp).split('.')[1] return f; } |
如果您碰巧使用AngularJS,那么这个货币过滤器肯定会有帮助:http://www.w3schools.com/angular/ng_filter_currency.asp
只针对未来的谷歌(或不一定是"谷歌"):
上面提到的所有解决方案都很好,但是,在这种情况下使用regexp可能是非常糟糕的事情。
因此,是的,您可以使用一些建议的选项,甚至编写一些原始但有用的内容,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | const strToNum = str => { //Find 1-3 digits followed by exactly 3 digits & a comma or end of string let regx = /(\d{1,3})(\d{3}(?:,|$))/; let currStr; do { currStr = (currStr || str.split(`.`)[0]) .replace( regx, `$1,$2`) } while (currStr.match(regx)) //Stop when there's no match & null's returned return ( str.split(`.`)[1] ) ? currStr.concat(`.`, str.split(`.`)[1]) : currStr; }; strToNum(`123`) // => 123 strToNum(`123456`) // => 123,456 strToNum(`-1234567.0987`) // => -1,234,567.0987 |
这里使用的regexp相当简单,循环将精确执行完成任务所需的次数。
您可能会更好地优化它,"干燥"代码等等。
然而,
1 | (-1234567.0987).toLocaleString(); |
(在大多数情况下)是一个更好的选择。
关键不在于执行速度或跨浏览器兼容性。
在您希望向用户显示结果编号的情况下,.ToLocaleString()方法使您能够与网站或应用程序的用户(无论其语言是什么)使用相同的语言。
根据EcmaScript文档,这种方法是在1999年引入的,我认为其原因是希望互联网在某一点上能够连接世界各地的人们,因此需要一些"内化"工具。
今天,互联网确实连接了我们所有人,因此,重要的是要记住,这个世界是一个更复杂的方式,我们可能会想象我们所有人都在互联网上。
显然,考虑到人的多样性,我们不可能保证每个人都有完美的用户体验,因为我们讲不同的语言,重视不同的事物等。正因为如此,尽可能多地将事物本地化更为重要。
因此,考虑到有一些特定的日期、时间、数字等表示标准,我们有一个工具来以最终用户首选的格式显示这些内容,那么不使用该工具(尤其是在我们希望向用户显示这些数据的情况下)是不是很少见,而且几乎是不负责任的?
对我来说,在这种情况下使用regexp而不是.toLocaleString()听起来有点像用javascript创建一个时钟应用程序,并以这种方式对其进行硬编码,这样它只显示布拉格时间(这对不住在布拉格的人来说是非常无用的),即使默认的行为是
1 | new Date(); |
是根据最终用户的时钟返回数据。
我已经调整了您的代码以在文本框(input type="text")中工作,因此我们可以实时输入和删除数字,而不会丢失光标。如果您在删除时选择范围,它也可以工作。您可以自由使用箭头和主/结束按钮。
谢谢你节省我的时间!
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 | //function controls number format as"1,532,162.3264321" function numberWithCommas(x) { var e = e || window.event; if (e.keyCode >= '35' && e.keyCode <= '40') return; //skip arrow-keys var selStart = x.selectionStart, selEnd = x.selectionEnd; //save cursor positions var parts = x.value.toString().split("."); var part0len = parts[0].length; //old length to check if new ',' would be added. Need for correcting new cursor position (+1 to right). //if user deleted ',' - remove previous number instead (without selection) if (x.selectionLength == 0 && (e.keyCode == 8 || e.keyCode == 46)) {//if pressed 8-backspace or 46-delete button var delPos = parts[0].search(/\d{4}/); if (delPos != -1) {//if found 4 digits in a row (',' is deleted) if (e.keyCode == 8) {//if backspace flag parts[0] = parts[0].slice(0, selStart - 1) + parts[0].slice(selEnd, parts[0].length); selEnd--; if (selStart > selEnd) selStart = selEnd; } else { parts[0] = parts[0].slice(0, selStart) + parts[0].slice(selEnd + 1, parts[0].length); selStart++; if (selEnd < selStart) selEnd = selStart; } } } var hasMinus = parts[0][0] == '-'; parts[0] = (hasMinus ? '-' : '') + parts[0].replace(/[^\d]*/g,""); //I'd like to clear old ',' to avoid things like 1,2,3,5,634.443216 parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g,","); //sets ',' between each 3 digits if (part0len < parts[0].length) { //move cursor to right if added new ',' selStart++; selEnd++; } else if (part0len > parts[0].length) { //..or if removed last one ',' selStart--; selEnd--; } x.value = parts.join("."); x.setSelectionRange(selStart, selEnd); //restoring cursor position } function saveSelectionLength(x) { x.selectionLength = x.selectionEnd - x.selectionStart; } |
要使用它,只需添加两个事件-onkeyup和onkeydown
1 |
这里有一个很好的解决方案,代码更少…
1 2 3 4 5 6 7 | var y =""; var arr = x.toString().split(""); for(var i=0; i<arr.length; i++) { y += arr[i]; if((arr.length-i-1)%3==0 && i<arr.length-1) y +=","; } |
印度数字系统
1 2 3 | var number ="323483.85" var decimal = number.split("."); var res = (decimal[0].length>3? numberWithCommas(decimal[0].substring(0,decimal[0].length-3))+ ',' :decimal[0]) + (decimal[0].length>3?decimal[0].substring(decimal[0].length-3,decimal[0].length):'') + '.' + decimal[1]; |
输出:3,23483.85
对于整数,我使用了一个非常简单的方法:
1 2 3 4 5 | var myNumber = 99999, myString = myNumber +""; myString.length > 3 ? return myString.substring(0, myString.length - 3) +"," + myString.substring(myString.length - 3) : return myString; |
我想我会分享一个小技巧,用于大数字格式。我没有插入逗号或空格,而是在"千"之间插入一个空的但可见的跨距。这使得数千个字符很容易被看到,但它允许以原始格式复制/粘贴输入,而不需要逗号/空格。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // This function accepts an integer, and produces a piece of HTML that shows it nicely with // some empty space at"thousand" markers. // Note, these space are not spaces, if you copy paste, they will not be visible. function valPrettyPrint(orgVal) { // Save after-comma text, if present var period = orgVal.indexOf("."); var frac = period >= 0 ? orgVal.substr(period) :""; // Work on input as an integer var val ="" + Math.trunc(orgVal); var res =""; while (val.length > 0) { res = val.substr(Math.max(0, val.length - 3), 3) + res; val = val.substr(0, val.length - 3); if (val.length > 0) { res ="<span class='thousandsSeparator'></span>" + res; } } // Add the saved after-period information res += frac; return res; } |
用这个CSS:
1 2 3 4 | .thousandsSeparator { display : inline; padding-left : 4px; } |
请参阅一个JSfiddle示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 | function addCommas(nStr) { nStr += ''; var x = nStr.split('.'); var x1 = x[0]; var x2 = x.length > 1 ? '.' + x[1] : ''; var rgx = /(\d+)(\d{3})/; while (rgx.test(x1)) { x1 = x1.replace(rgx, '$1' + ',' + '$2'); } return x1 + x2; } addCommas(parseFloat("1099920.23232").toFixed(2)); //Output 1,099,920.23 |
现在应该可以了…如果数字是小数,则编辑为添加小数点。
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 | function makedollars(mynumber) { mynumber = mynumber.toString(); var numberend=""; if(mynumber.split('.').length>1){ var mynumbersplit = mynumber.split('.'); mynumber = mynumbersplit[0]; numberend= mynumbersplit[1]; } var mn = mynumber.length; if (mn <= 3) { return mynumber + numberend; } var grps = []; while (mn > 3) { grps.push(mynumber.substring(mn,mn - 3)); mn = mn - 3; } grps.push(mynumber.substring(mn,mn - 3)); grps.reverse(); grps.join(","); if(numberend!=""){ grps = grps +"."+numberend;} return grps; } |
可以使用for循环将逗号添加到数字中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | function convertNumber(){ var _cash = cash.toString() var _formattedCash = '' var count = 0 for (let i = _cash.length; i >= 0; i--) { _formattedCash += _cash.substring(i,i+1) if(count == 3 && i > 0){ _formattedCash += ',' count = 0 } count++ } var _format = '' for (let i = _formattedCash.length; i >= 0; i--) { _format += _formattedCash.substring(i, i + 1) } return 'Ksh ' + _format; } |
还有一个..(对于int的问题)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function insertCommas(str) { var a = str.split(""); a.reverse(); var t, i = 0, arr = Array(); while (t = a.shift()) { if (((i++ % 3) == 0) && arr.length > 0) arr.unshift(","); arr.unshift(t); } return arr.join(""); } |
您可以使用
1 2 | double number = 1234567; System.out.printf("%,.2f" , number); |