JavaScript处理数字分位符号
昨天做一个页面有一个需求,需要把服务器取过来的数字(也有可能是数字字符串),将小数点前的数字每隔三位添加一个逗号(前面数是一个四位数的值)。比如取到的值是123456
,要将其转换成123,456
。搜索了一下,这叫数字分位符号。
为了方便阅读小数点前后的数字可以被分组,由于国际上语言里最常见的数字读法是千位分位,写法的分组也是在千位数上。 如果当地习俗是用句点作小数点,千位的分号一般是逗号或空格。如果习俗里小数点是逗号,千位分号一般是句点或空格。由于可能产生歧义,国际标准建议、国际度量衡局更是要求用空格而不要用逗号或点。
不同国家有不同的标准要求,我们看看我国的标准:
为便于阅读,四位以上的整数或小数,可采用以下两种方式分节:
- 千分撇: 整数部分每三位一组,以
,
分节。小数部分不分节。四位以内的整数可以不分节。如:624,000
、92,300,000
、19,351,235.235767
,1256
- 千分空: 从小数点起,向左和向右每三位数字一组,组间空四分之一个汉字,即二分之一个阿拉伯数字的位置。四位以内的整数可以不加千分空。如:
55 235
、367.346
、23 98 235
、358.238
、368
可见,中国正式场合的数字用法并非是以万位数为一组来分节的。诸如123,4567.89
的表示法是错误的。
JavaScript如何处理数字分位符
在这样的一个实际需求当中,取到的值不外呼是两种,其一它就是一个数字类型(整型123456
或者浮点型12345.09
),其二是一个数字字符串,比如"123456"
。那回到主题上,现在需要将这样的数字或字符串做处理。
- 需要创建一个函数,比如
addCommas()
,并且给这个函数传递一个参数val
。需要注意的是,这个val
值有可能是数字类型,也有可能是字符类型。 - 不管获取的
val
是什么类型,首先通过toString()
方法,将其转换成字符串 - 由于取到的
val
值有可能是一个浮点数,而我们是需要给小数点前面的整数部分添加分位符号,
;在JavaScript中可以通过split(".")
将这个val
转换成一个数组aIntNmu
。如果val
值是一个整数,那么得到的数组只有一个值,如果val
是一个浮点数,那么将会以小数点为分隔点,数整会有两个元素值。我们要处理的将是aIntNum[0]
。 - 通过正则
replace()
主法给aIntNum[0]
做替换,这里需要一个正则规则,比如/(\d+)(\d{3})/
。正则这部分,对于我这样的菜鸟而言还是很吃力的,不过这有个在线工具,可以检测并解释其函数。 - 如果你想让JavaScript处理数字千分位更符合国家的标准,那么在做数据替换时,还需要做一个条件判断。比如说,只有当
aIntNum[0].length
大于或等于5
的时候才添加分位符。 - 返回处理的数字
上面方法是通过数组来处理的,其实还可以直接通过字符串处理来解决。比如通过indexOf(".")
对数字分隔,再配合for
循环、charAt()
和substr()
等方法给数字添加分位符。接下来,我们一起看看代码具体如何写。
数组方案
根据前面的介绍的,先用数组的方式来做:
function addCommas(val) {
//根据`.`作为分隔,将val值转换成一个数组
var aIntNum = val.toString().split('.');
// 整数部分
var iIntPart = aIntNum[0];
// 小数部分(传的值有小数情况之下)
var iFlootPart = aIntNum.length > 1 ? '.' + aIntNum[1] : '';
var rgx = /(\d+)(\d{3})/;
// 如果整数部分位数大于或等于5
if (iIntPart.length >= 5) {
// 根据正则要求,将整数部分用逗号每三位分隔
while (rgx.test(iIntPart)) {
iIntPart = iIntPart.replace(rgx, '$1' + ',' + '$2');
}
}
return iIntPart + iFlootPart;
}
上面的方法生不生效,难证一下就知道了:
addCommas(1234); // =>"1234"
addCommas(12345);// =>"12,345"
addCommas(123456);//=>"123,456"
addCommas(123456.4321);//=>"123,456.4321"
addCommas(123456.54321);//=>"123,456.54321"
addCommas(123456.654321);//=>"123,456.654321"
上面的方法只能小数点前面的数做了处理,如果需要对小数点后面的也做相应的处理,就需要做一下处理:
function addCommas(val) {
//根据`.`作为分隔,将val值转换成一个数组
var aIntNum = val.toString().split('.');
// 整数部分
var iIntPart = aIntNum[0];
// 小数部分(传的值有小数情况之下)
var iFlootPart = aIntNum.length > 1 ? '.' + aIntNum[1] : '';
var rgx = /(\d+)(\d{3})/;
// 如果整数部分位数大于或等于5
if (iIntPart.length >= 5) {
// 根据正则要求,将整数部分用逗号每三位分隔
while (rgx.test(iIntPart)) {
iIntPart = iIntPart.replace(rgx, '$1' + ',' + '$2');
}
}
// 如果小数部分位数大于或等于5
if (iFlootPart && iFlootPart.length >= 5) {
// 根据正则要求,将小数部分用每三位分隔按空格号分开
while (rgx.test(iFlootPart)) {
iFlootPart = iFlootPart.replace(/(\d{3})/g, '$1 ');
}
}
// 将整数部分和小数组部分合并在一起,并返回
return iIntPart + iFlootPart;
}
调试器里继续跑一下测试代码:
addCommas(1234);//=>"1234"
addCommas(12345);//=>"12,345"
addCommas(123456);//=>"123,456"
addCommas(123456.4321);//=>"123,456.432 1"
addCommas(123456.54321);//=>"123,456.543 21"
addCommas(123456.654321);//=>"123,456.654 321 "
效果是有,但感觉怪怪的。
上面的代码可以精简一下,变成这样:
function addCommas(val) {
var aIntNum = val.toString().split('.');
if (aIntNum[0].length >= 5) {
aIntNum[0] = aIntNum[0].replace(/(\d)(?=(\d{3})+$)/g, '$1,');
}
if (aIntNum[1] && aIntNum[1].length >= 5) {
aIntNum[1] = aIntNum[1].replace(/(\d{3})/g, '$1 ');
}
return aIntNum.join('.');
}
最后得到的效果就是一样。
将上面代码中的正则条件换换,也一样可以达到相同的效果:
function addCommas(val) {
var aIntNum = val.toString().split(".");
if (aIntNum[0].length >= 5) {
aIntNum[0] = aIntNum[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
if (aIntNum[1] && aIntNum[1] >= 5) {
aIntNum[1] = aIntNum[1] ? aIntNum[1].replace(/\B(?=(\d{3})+(?!\d))/g, " ") : " ";
}
return aIntNum.join(".");
}
字符串方案
前面也说了,除了将传参转换成数组去处理之外,还可以直接对传参进行字符串的操作。下面收集了几种方法,虽然达到需求,但还是略有不同之处。比如小数部分用的不是空格分开,而是使用逗号分开。另外一点,就是没找到如何超过四位数才进行分隔处理。希望有高手能指点其中不足之处。
方法1
function addCommas(val) {
while (/(\d+)(\d{3})/.test(val.toString())) {
val = val.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2');
}
return val;
}
方法2
function addCommas(val) {
var sIntNum = val.toString(),
bIndex = sIntNum.indexOf('.');
return sIntNum.replace(/\d(?=(?:\d{3})+(?:\.|$))/g, function($0, i) {
return bIndex < 0 || i < bIndex ? ($0 + ',') : $0;
});
}
方法3
function addCommas(val) {
return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
方法4
function addCommas(val) {
return (val + "").replace(/\b(\d+)((\.\d+)*)\b/g, function(a, b, c) {
return (b.charAt(0) > 0 && !(c || ".").lastIndexOf(".") ? b.replace(/(\d)(?=(\d{3})+$)/g, "$1,") : b) + c;
});
}
总结
上面整理了使用数组或者直接操作字符串的几种方法,将一个数字或数字字符串,按照千分位的方式给其添加对应的分隔符,比如,
或空格。虽然达到了一定的需求,但感觉里面的还存在一定的问题,只是没有找到问题所在。希望大婶们指点其中不对之处,如果您有更好的方案,欢迎在下面的评论中与我们一起分享。
扩展阅读
- how to print a number with commas as thousands separators in javascript
- 5 MISSING JAVASCRIPT NUMBER FORMAT FUNCTIONS
如需转载,烦请注明出处:https://www.fedev.cn/javascript/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript.htmlnike air max 1 hyperfuse