JS正则实现数值千分位
今天在看vuex的demo时,看到引用了一个currency脚本文件,通过仔细分析其中的代码,发现其主要作用就是进行数值千分位的处理。现简要梳理一下从这个脚本中学习吸收到的东西。场景:进行js中数字的整数部分千分位划分input:1234.56478output:1,234.5678先说说大体的实现思路,先将该数字转换成字符串,获取整数部分,...
今天在看vuex的demo时,看到引用了一个currency脚本文件,通过仔细分析其中的代码,发现其主要作用就是进行数值千分位的处理。现简要梳理一下从这个脚本中学习吸收到的东西。
场景:
进行js中数字的整数部分千分位划分
input:1234.56478
output:1,234.5678
先说说大体的实现思路,先将该数字转换成字符串,获取整数部分,然后将整数部分进行每3位的划分,之后再将千分位后的整数部分与小数部分拼接。其中的难点就在于整数部分的千分位划分上。
currency脚本中的处理方法是,使用正则表达式reg = /(\d{3}(?=\d))/
进行匹配。
刚开始看这个表达式,也是有些疑惑的,表达式的前半部分(\d{3})
很好理解,就是匹配3个数字,但是后半部分(?=\d)
我刚看的时候还是没看懂。后来查了一下正则表达式(?=pattern)
的语法,得到如下描述
正向肯定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,”Windows(?=95|98|NT|2000)”能匹配”Windows2000”中的”Windows”,但不能匹配”Windows3.1”中的”Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
初看这个描述的时候,也是感觉云里雾里。不过结合代码中的实际列子,自己算是理解了其中的意思,请看如下列子。
//列1
var a = '13245646';
var reg = /(\d{3})(\d)/g
a.replace(reg,'$1-$2-');
//输出
//"132-4-564-6-"
显然我们看到$1
指向的是(/d{3})
而$2
指向的是(\d)
我们在看看使用?=
的效果
//列2
var a = '13245646';
var reg = /(\d{3})(?=\d)/g
a.replace(reg,'$1-$2-');
//输出
//"132-$2-456-$2-46"
可以看到$1
还是和之前一样,但是$2
却发生了变化,它不在指代某一个分组,而是单纯的文字了。这是因为在我们这个表达式中只有分组一(\d{3})
是生效的,而没有其他分组,我们来验证一下
//列3
var a = '13245646';
var reg = /(\d{3})(?=\d)(\d)/g
a.replace(reg,'$1-$2-');
//输出
//"132-4-564-6-"
发现没有!!!这个结果和我们第一个列子的结果是一模一样的,那么文章开头看到的解释中的这部分话就很好理解了
这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用
同样,通过这三个列子的结果,我们也可以理解下面这句话了
预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
我们再来对比一下列1和列2
var a = '13245646';
//列1
var reg1 = /(\d{3})(\d)/g
var reg2 = /(\d{3})(?=\d)/g
console.log('reg1:', a.match(reg1) )
console.log('reg2:',a.match(reg2) )
//输出
//reg1: (2) ["1324", "5646"]
//reg2: (2) ["132", "456"]
可以看到reg1在下一次的匹配中,是从(\d)之后的下一个字符开始匹配,而reg2中的下一次匹配时,却是直接从(\d{3})的下一个字符开始匹配。
所以这就解释了上面的那段话了。
好了,不多说废话了,给出具体的解决方法吧。show me the code .
function reverseStr(str){
return str.split('').reverse().join('');
}
function replace3Int(str){
return str.replace(/(\d{3})(?=\d)/g, '$1,')
}
function currency (intStr) {
return reverseStr(replace3Int(reverseStr(intStr) ))
}
var a = '12345678';
currency(a);
// "12,345,678"
以上方法给出了如何对整数部分进行千分位,结合小数部分的自行处理即可。
我在网上也看到了另外一种很巧妙的方法来实现,使用的是number.toLocaleString方法
但是这个方法有一点需要注意:那就是小数部分的一定要单独处理
example
var a = 123456789;
a.toLocaleString(); //"123,456,789"
var b = 14654651156.21345
b.toLocaleString(); //"14,654,651,156.213"
有没有发现,小数部分被直接截取了3位,所以小数部分还是需要单独处理一下的。
更多推荐
所有评论(0)