前言
在一些涉及到比较大的数字的场景中,比如人数,金额等,我们常常需要对这些数字进行千分位,然后逗号分隔,这样会比较好阅读。
比如
123456789
如果是千分位分隔
123,456,789
对比这两种,我们肯定是选择第二种,方便阅读。
实现
那怎么实现呢?
一般是利用正则表达式
function formatNumber(num) {
const reg = /(\d)(?=(\d{3})+$)/g
return num.toString().replace(reg, '$1,')
}
formatNumber(12345678) // "12,345,678"
formatNumber(8765432188) // "8,765,432,188"
测试通过。
但是这是基于数字是整数型的正则,如果你的数字是有小数点的,结果如下
formatNumber(1234.5678) // "1234.5,678"
期望是"1,234.5678"
,不需要对小数点部分做千分位分隔,只需要对整数部分做千分位分隔,
实际是 "1234.5,678"
所以需要对正则进行优化。
function formatNumber(num) {
const reg = /(\d)(?=(\d{3})+\.)/g
return num.toString().replace(reg, '$1,')
}
formatNumber(1234.5678) // "1,234.5678"
formatNumber(1234) // "1234"
从上面例子可以看到,
如果数字带有小数点,则是有效果的
但是如果数字是没有小数点的,这个正则是不起作用的, 所以需要对两个正则整合起来,实现对整数和小数的支持
function formatNumber(num) {
num = num.toString()
let reg = num.indexOf('.') > -1 ? /(\d)(?=(\d{3})+\.)/g : /(\d)(?=(\d{3})+$)/g
return num.replace(reg, '$1,')
}
formatNumber(1234.5678) // "1,234.5678"
formatNumber(1234) // "1,234"
下面对正则/(\d)(?=(\d{3})+$)/g
和/(\d)(?=(\d{3})+\.)/g
进行分析:
- 这个正则主要是利用
d{3}
每3位数字匹配一次,匹配到就对前面的那个数字加上逗号,以此类推。 - 正则这里加了
$
和.
,是为了优先后面的凑成3位,开头如果不足3位就不处理。 - 这里还使用了正则一个表达式
(?=pattern)
,术语叫零宽断言
,或者也叫正向肯定预查
。
实现千分位分隔,核心点就是这个,下面来讲讲这个正则表达式。
零宽断言(正向肯定预查)
(?=pattern), 是指配合正则表达式进行匹配,但是不获取该匹配。下次匹配还是从该位置开始。
配合例子来讲会比较好理解:
var regA = /答案(?=cp3)/
console.log('答案cp3'.match(regA)) // ["答案"]
var regB = /cp3(?=cp3)/g
console.log('cp3cp3cp3cp3'.match(regB)) // ["cp3", "cp3", "cp3"]
第一个例子可以看到匹配到了答案cp3
,但是只获取到了答案
,cp3
不获取
第二个例子可以看到匹配到了cp3cp3
,只获取到了cp3
,下次匹配从第二个cp3
开始,以此类推,最终输出三个cp3
。
结合上面的千分位分隔例子,因为我们使用了零宽断言,因为它下次匹配还是从该位置开始,所以就导致每个数字都会被匹配到,直到结尾
let reg = /(\d)(?=(\d{3})+)/g
'1234567890'.replace(reg, (match,$1, $2, index, str) => {
console.log(match,$1, $2, index, str)
return $1 + ','
})
输出 1 1 890 0 1234567890
输出 2 2 678 1 1234567890
输出 3 3 789 2 1234567890
输出 4 4 890 3 1234567890
输出 5 5 678 4 1234567890
输出 6 6 789 5 1234567890
输出 7 7 890 6 1234567890
返回 "1,2,3,4,5,6,7,890"
所以我们在零宽断言里面加上$
或者.
去约束条件,限制优先匹配结尾,开头不足3位就不处理
let reg = /(\d)(?=(\d{3})+$)/g
'1234567890'.replace(reg, (match,$1, $2, index, str) => {
console.log(match,$1, $2, index, str)
return $1 + ','
})
输出 1 1 890 0 1234567890
输出 4 4 890 3 1234567890
输出 7 7 890 6 1234567890
返回 "1,234,567,890"
这样子就没有问题了。
总结
以上就是利用正则实现千分位分隔的总结
完整代码:
function formatNumber(num) {
num = num.toString()
let reg = num.indexOf('.') > -1 ? /(\d)(?=(\d{3})+\.)/g : /(\d)(?=(\d{3})+$)/g
return num.replace(reg, '$1,')
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!