我试图用逗号作为千位分隔符在JavaScript中打印一个整数。例如,我想将数字1234567显示为“1,234,567”。我该怎么做呢?
我是这样做的:
function numberWithCommas(x) {
x = x.toString();
var pattern = /(-?\d+)(\d{3})/;
while (pattern.test(x))
x = x.replace(pattern, "$1,$2");
return x;
}
有更简单或更优雅的方式吗?如果它也适用于浮点数会很好,但这不是必需的。它不需要特定于语言环境来决定句点和逗号。
我使用了克里答案中的想法,但简化了它,因为我只是为了我的特定目的而寻找简单的东西。这是我做的:
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
这是你真正需要知道的。
@Neils Bom询问了正则表达式的工作原理。我的解释有点长。它不适合评论,我不知道在哪里放,所以我在这里做。如果有人有任何其他建议,请告诉我。
正则表达式使用2个前瞻断言:一个正向查找字符串中的任何一个点,后面有一个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”,所以没有逗号。等等。 “\ B”使正则表达式不会在字符串的开头加上逗号。
@ neu-rah提到如果小数点后面有3位以上的数字,这个函数会在不受欢迎的地方添加逗号。如果这是一个问题,您可以使用此功能:
function numberWithCommas(x) {
var parts = x.toString().split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return parts.join(".");
}
我认为这是最短的正则表达式:
/\B(?=(\d{3})+\b)/g
"123456".replace(/\B(?=(\d{3})+\b)/g, ",")
我检查了几个数字,它工作。
如果它是由所有浏览器(Safari)本地提供的话,Number.prototype.toLocaleString()
会很棒。
我检查了所有其他答案,但似乎没有人填充它。这是对此的poc,实际上是前两个答案的组合;如果toLocaleString
工作它使用它,如果它不使用它自定义功能。
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));
可以使用浏览器的Intl
对象以国际友好的方式插入千位分隔符:
Intl.NumberFormat().format(1234);
// returns "1,234" if the user's locale is en_US, for example
有关更多信息,请参阅MDN's article on NumberFormat,您可以指定区域设置行为或默认为用户的行为。这更加万无一失,因为它尊重当地的差异;许多国家/地区使用句点来分隔数字,而逗号表示小数。
Intl.NumberFormat尚未在所有浏览器中提供,但它适用于最新的Chrome,Opera和IE。 Firefox的下一个版本应该支持它。 Webkit似乎没有实现的时间表。
您可以使用此过程来格式化您需要的货币。
var nf = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
nf.format(123456.789); // ‘$123,456.79’
有关详细信息,您可以访问此链接。
https://www.justinmccandless.com/post/formatting-currency-in-javascript/
如果您正在处理货币值和格式化很多,那么可能值得添加处理大量边缘情况和本地化的微小accounting.js:
// 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扫描,因此没有正则表达式。
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://jsperf.com/number-formatting-with-commas/5
2015.4.26:当num <0时解决问题的次要修复。见https://jsfiddle.net/runsun/p5tqqvs3/
这是一个简单的函数,可以为千位分隔符插入逗号。它使用数组函数而不是RegEx。
/**
* 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
使用此代码处理印度的货币格式。国家代码可以更改为处理其他国家/地区货币。
let amount =350256.95
var formatter = new Intl.NumberFormat('en-IN', {
minimumFractionDigits: 2,
});
// Use it.
formatter.format(amount);
输出:
3,50,256.95
我在写这篇文章之前写了这篇文章。没有正则表达式,你可以真正理解代码。
$(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' ) );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="theDudeAbides"></div>
对我来说,最好的答案是像一些成员所说的那样使用toLocaleString。如果您想要包含'$'符号,只需添加语言和类型选项即可。以下是将数字格式化为墨西哥比索的示例
var n = 1234567.22
alert(n.toLocaleString("es-MX",{style:"currency", currency:"MXN"}))
捷径
1234567.22.toLocaleString("es-MX",{style:"currency", currency:"MXN"})
我很惊讶没有人提到Number.prototype.toLocaleString。它是在JavaScript 1.5(1999年推出)中实现的,因此它基本上支持所有主流浏览器。
var n = 34523453.345
n.toLocaleString()
"34,523,453.345"
通过包含Intl,它也适用于v0.12的Node.js
请注意,此函数返回一个字符串,而不是一个数字。
如果你想要不同的东西,Numeral.js可能会很有趣。
让我试着改善uKolka的answer,也许可以帮助别人节省一些时间。
使用Numeral.js。
document.body.textContent = numeral(1234567).format('0,0');
<script src="//cdnjs.cloudflare.com/ajax/libs/numeral.js/1.4.5/numeral.min.js"></script>
只有当它的Number.prototype.toLocaleString()不是问题时,你才应该使用browser compatibilty。
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(".");
}
编辑:该功能仅适用于正数。例如:
var number = -123123231232;
formatNumber(number)
输出:“123,123,231,232”
但回答上面的问题toLocaleString()
方法只是解决了问题。
var number = 123123231232;
number.toLocaleString()
输出:“123,123,231,232”
欢呼!
我认为这个功能将处理与此问题相关的所有问题。
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;
}
我添加了Tofixed Aki143S的解决方案。此解决方案使用数千个分隔符的点和精度的逗号。
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('');
};
例子;
formatNumber(17347, 0) = 17.347
formatNumber(17347, 3) = 17.347,000
formatNumber(1234563.4545, 3) = 1.234.563,454
已经有很多好的答案了。这是另一个,只是为了好玩:
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] : "");
}
一些例子:
format(77.03453, 2); // "77.03"
format(78436589374); // "78,436,589,374"
format(784, 4); // "784.0000"
format(-123456); // "-123,456"
另一种方法,支持小数,不同的分隔符和负数。
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 = ((number < 0) ? '-' : '') + n.substr(0, i)
;
for(;i<n.length;i+=3) {
if(i!=0) f+=ts;
f+=n.substr(i,3);
}
if(dp > 0)
f += ds + parseFloat(number).toFixed(dp).split('.')[1]
return f;
}
@Jignesh Sanghani的一些更正,不要忘记赞成他的评论。
您还可以使用Intl.NumberFormat构造函数。这是你如何做到的。
resultNumber = new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(yourNumber);
来自@ user1437663的解决方案非常棒。
谁真正了解解决方案正准备理解复杂的正则表达式。
一个小的改进,使其更具可读性:
function numberWithCommas(x) {
var parts = x.toString().split(".");
return parts[0].replace(/\B(?=(\d{3})+(?=$))/g, ",") + (parts[1] ? "." + parts[1] : "");
}
模式以\ B开头,以避免在单词的开头使用逗号。有趣的是,模式返回为空,因为\ B不会使“游标”前进(同样适用于$)。
O \ B后面是一个鲜为人知的资源,但它是Perl正则表达式的强大功能。
Pattern1 (? = (Pattern2) ).
神奇的是,括号中的内容(Pattern2)是一个跟随前一个模式(Pattern1)的模式,但没有前进光标,也不是返回模式的一部分。这是一种未来的模式。当有人期待但真的不走路时,这是相似的!
在这种情况下,pattern2是
\d{3})+(?=$)
它表示3位数(一次或多次),后跟字符串结尾($)
最后,Replace方法更改所有出现的模式(空字符串)以用于逗号。这只发生在剩余部分是3位数的倍数的情况下(未来光标到达原点的末尾的情况)。
我认为你的解决方案是我见过的较短的解决方案之一。我不认为有任何标准的JavaScript函数来做这种事情,所以你可能是你自己的。
我检查了CSS 3规范,看看是否可以在CSS中执行此操作,但除非您想要自己的<span>
中的每个数字,我认为这是不可能的。
我确实在Google Code找到了一个看起来很有希望的项目:flexible-js-formatting。我没有使用它,但它看起来非常灵活,并使用JsUnit进行单元测试。开发人员也有很多关于这个主题的帖子(虽然很旧)。
一定要考虑国际用户:许多国家使用空格作为分隔符,并使用逗号将小数与数字的整数部分分开。
仅适用于未来的Google员工(或不一定是“Google员工”):
上面提到的所有解决方案都很精彩,但是,在这种情况下使用RegExp可能是非常糟糕的事情。
所以,是的,您可以使用一些提议的选项,甚至可以编写原始但有用的东西,如:
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
这里使用的正则表达式相当简单,循环将精确地完成完成工作所需的次数。
你可以更好地优化它,“DRYify”代码等等。
然而,
(-1234567.0987).toLocaleString();
(在大多数情况下)将是一个更好的选择。
重点不在于执行速度或跨浏览器兼容性。
在您希望向用户显示结果编号的情况下,.toLocaleString()方法为您提供超级大国,可以与您的网站或应用程序的用户说出相同的语言(无论她/他的语言是什么)。
根据ECMAScript文档的这种方法是在1999年引入的,我认为其原因是希望互联网在某种程度上能够连接世界各地的人们,因此,需要一些“内化”工具。
今天,互联网确实连接了我们所有人,因此,重要的是要记住世界是一种我们可能想象的更复杂的方式,而且(几乎)我们所有人都在互联网上。
显然,考虑到人的多样性,不可能为每个人保证完美的用户体验,因为我们说不同的语言,重视不同的事物等等。正因为如此,尝试尽可能多地本地化事物更为重要。 。
因此,考虑到日期,时间,数字等的表示有一些特定的标准,并且我们有一个工具以最终用户首选的格式显示这些东西,并不是那么罕见,几乎不负责任使用该工具(特别是在我们想要向用户显示此数据的情况下)?
对我来说,在这种情况下使用RegExp而不是.toLocaleString()听起来有点像创建一个带有JavaScript的时钟应用程序并以这种方式对其进行硬编码,因此它只显示布拉格时间(这对于那些不住在布拉格的人即使是默认的行为
new Date();
是根据最终用户的时钟返回数据。
var number = 1234567890; // Example number to be converted
⚠请注意,javascript的maximum integer值为9007199254740991
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"
NumberFormat(不支持Safari):
var nf = new Intl.NumberFormat();
nf.format(number); // "1,234,567,890"
根据我的检查(至少是Firefox),它们在性能方面或多或少相同。
你看到那些热情的球员吗?也许你可以打高尔夫了。这是我的中风。
n => `${n}`.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " ").replace(/(?<=\.(\d{3})+)\B/g, " ")
使用
THIN SPACE(U + 2009)作为千分隔符,正如国际单位制表示在the eighth edition(2006) of their publication “SI Brochure: The International System of Units (SI)”中所做的那样(参见§5.3.4。)。 The ninth edition(2019)建议使用空间(参见§5.4.4。)。你可以使用你想要的任何东西,包括逗号。
const integer_part_only = n => `${n}`.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " I ");
const fractional_part_only = n => `${n}`.replace(/(?<=\.(\d{3})+)\B/g, " F ");
const both = n => fractional_part_only(integer_part_only(n));
function demo(number) { // I’m using Chrome 74.
console.log(`${number}
→ "${integer_part_only(number)}" (integer part only)
→ "${fractional_part_only(number)}" (fractional part only)
→ "${both(number)}" (both)
`);
}
demo(Math.random() * 10e5);
demo(123456789.01234567);
demo(123456789);
demo(0.0123456789);
.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " I ")
.replace(……, " I ")
把“我”
/……/g
每个人
\B
两个相邻数字之间
(?=……)
POSITIVE LOOKAHEAD,右边是
(\d{3})+
一个或多个三位数的块
\b
后跟一个非数字,例如,一个句号,字符串的结尾,等等,
(?<!……)
NEGATIVE LOOKBEHIND排除左侧部分
\.\d+
是一个点后跟数字(“有一个小数点分隔符”)。.replace(/(?<=\.(\d{3})+)\B/g, " F ")
.replace(……, " F ")
把“F”
/……/g
每个人
\B
两个相邻数字之间
(?<=……)
POSITIVE LOOKBEHIND,左边是
\.
小数分隔符
(\d{3})+
后跟一个或多个三位数块。
\d
匹配任何数字(阿拉伯数字)。相当于
[0-9]
。例如,
/\d/
或/[0-9]/
与2
的B2 is the suite number
相匹配。
\b
匹配单词边界。这是一个单词字符未被跟随或前面跟另一个单词字符的位置,例如在字母和空格之间。请注意,匹配中不包括匹配的字边界。换句话说,匹配的字边界的长度为零。
例子:
/\bm/
与m
中的moon
相匹配;/oo\b/
与oo
中的moon
不匹配,因为oo
后面是n
,这是一个单词字符;/oon\b/
匹配oon
中的moon
,因为oon
是字符串的末尾,因此后面没有单词字符;/\w\b\w/
永远不会匹配任何东西,因为一个单词字符永远不会被非单词和单词字符所遵循。
\B
匹配非单词边界。这是前一个和下一个字符属于同一类型的位置:要么两者都必须是单词,要么两者都必须是非单词。例如两个字母之间或两个空格之间。字符串的开头和结尾被视为非单词。与匹配的字边界相同,匹配的非字边界也不包括在匹配中。
例如,
/\Bon/
在on
匹配at noon
;/ye\B/
在ye
匹配possibly yesterday
。
我建议使用phpjs.org的number_format()
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 Fiddle。
更新于26/11/2017
这是一个小提琴作为一个略有修改输出的Stack Snippet:
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);
.as-console-wrapper {
max-height: 100% !important;
}
这是@ mikez302的答案的变体,但修改为支持带小数的数字(根据@ neu-rah的反馈,numberWithCommas(12345.6789) - >“12,345.6,789”而不是“12,345.6789”
function numberWithCommas(n) {
var parts=n.toString().split(".");
return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",") + (parts[1] ? "." + parts[1] : "");
}
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
使用正则表达式
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()
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
ref MDN:Number.prototype.toLocaleString()
使用Intl.NumberFormat()
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"
在这里演示
<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);
}
</script>
<FORM NAME="myform">
<INPUT TYPE="text" NAME="number1" VALUE="123456789">
<br>
<INPUT TYPE="button" NAME="button" Value="=>" onClick="commas()">
<br>Using Regular expression
<br>
<INPUT TYPE="text" ID="result1" NAME="result1" VALUE="">
<br>Using toLocaleString()
<br>
<INPUT TYPE="text" ID="result2" NAME="result2" VALUE="">
<br>Using Intl.NumberFormat()
<br>
<INPUT TYPE="text" ID="result3" NAME="result3" VALUE="">
</FORM>
性能
原生JS功能。支持IE11,Edge,最新的Safari,Chrome,Firefox,Opera,iOS上的Safari和Android上的Chrome。
var number = 3500;
console.log(new Intl.NumberFormat().format(number));
// → '3,500' if in US English locale
感谢大家的回复。我已经建立了一些答案,以制定更“一刀切”的解决方案。
第一个片段添加了一个模拟PHP的number_format()
到Number原型的函数。如果我格式化一个数字,我通常需要小数位,所以该函数需要显示小数位数。有些国家使用逗号作为十进制和小数作为千位分隔符,因此该函数允许设置这些分隔符。
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);
}
您将使用如下:
var foo = 5000;
console.log(foo.numberFormat(2)); // us format: 5,000.00
console.log(foo.numberFormat(2, ',', '.')); // european format: 5.000,00
我发现我经常需要为数学运算取回数字,但是parseFloat将5,000转换为5,只需取第一个整数值序列。所以我创建了自己的浮点转换函数并将其添加到String原型中。
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));
}
现在您可以使用以下两个函数:
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