梳理思路
要先明白的是,我们将要转换成的数字格式是这样:从个位往左数起,每三位前插入一个千位分隔符,
,即可以想象成我们要把每三位数字前面的那个空""
匹配出来,并替换成千位分隔符,
。每个千位分隔符后面的数字个数是3个或3的倍数个。
代码书写
创建一个正则表达式字面量,并加上全局匹配修饰符g。var reg = //g;
W3C对全局匹配的解释是:查找所有匹配而非在找到第一个匹配后停止。
因为需要从右往左匹配,所以表示结尾的$
是必须要有的。三位数字用\d{3}
来表示,由于我们不知道究竟有多少组这样的三位数字,所以需要在\d{3}
后面加上+
,来表示匹配任何包含至少一组三位数字的字符串。至目前,/(\d{3})+$/g
表示作为结尾的3个或3的倍数个数字。
由于要替换的是每三位数(从末尾起)紧前面的那个""
,所以需要用到正向预查,即?=n
(匹配任何其后紧接指定字符串 n 的字符串)。正向预查咋用呢?这里先举个例子:有一个字符串var str = "abaaaaa";
,我们想把后面跟着字符b的字符a表示出来,于是正则表达式写法:var reg = /a(?=b)/g;
,匹配的是后面紧跟着字符b
的字符a
,字符串str
中只有一个符合条件的a
,最后查看匹配结果为["a"]。这个例子的代码如下:
var str = "abaaaaa",
reg = /a(?=b)/g;
console.log(str.match(reg));
复制代码
粗略了解正向预查之后,回到原来的案例,我们可以写成/(?=(\d{3})+$)/g;
,为什么(?=...)
前面什么也不写呀?因为我们要找的是那些后面紧跟着三位数字的""
呀,空当然什么都不用写了。 我们来检验一下,是不是匹配出来三个""
?
var str = "10000000000",
reg = /(?=(\d{3})+$)/g;
console.log(str.match(reg));
复制代码
结果如下,果然是三个""
。
var str = "10000000000",
reg = /(?=(\d{3})+$)/g;
console.log(str.replace(reg, ","));
复制代码
结果如下,转换成功。
但是,还没完…… 现在是十一位数字,如果再加一个0,凑够十二位数呢,它可是3的倍数,我们试验一下:
var str = "100000000000",
reg = /(?=(\d{3})+$)/g;
console.log(str.replace(reg, ","));
复制代码
结果变成了这样:
这串数字最前面也被添加了一个,
。这个原因就不解释了,你们应该明白为什么。那么怎么解决呢?我们对代码进行一下完善,在\d
前面加一个非单词边界\B
,用来表示所匹配的这个空后面不能是一个单词边界,这样就可以把最前面的这个,
去掉了。 最终的代码如下
var str = "100000000000",
reg = /(?=(\B\d{3})+$)/g;
console.log(str.replace(reg, ","));
复制代码
总结
综上,”把一串整数转换成千位分隔形式“这个案例就说完了。我再把这个案例用到的一些知识点梳理一下。
g
是表示全局匹配的修饰符,全局匹配指查找所有匹配而非在找到第一个匹配后停止。$
是表示结尾的量词,如n$
,匹配的是任何以n为结尾的字符串。\d
是查找数字的元字符。n{X}
是匹配包含 X 个 n 的序列的字符串的量词。n+
是匹配任何包含至少一个 n 的字符串的量词。?=n
正向预查,用于匹配任何其后紧接指定字符串 n 的字符串。match()
String对象的方法,作用是找到一个或多个正则表达式的匹配。replace()
String对象的方法,作用是替换与正则表达式匹配的子串。\B
是表示匹配非单词边界的元字符,与其互为补集的元字符是\b
,表示匹配单词边界。
作者:TONGZ
链接:https://juejin.im/post/5abb5b01f265da237f1e5a92
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。