
前言:
腾讯曾经出过这样一道面试题:
如何给一串数字用千分制表示?比如9999999999变成9,999,999,999
大家可能会说:用操作字符串的办法做,变成字符串,先除以3,看有几对,然后再加逗号…………(省略无数个步骤,这实在是太麻烦啦。。)
也有小伙伴说,可以用(123456789.123).toLocaleString('en-US')
。没错,但是本文的思想是想要探讨如何用正则来解答,旨在熟悉正则。(tips:.toLocaleString('en-US')
不能对小数点后超过3位的数字进行,
分割)
那么,让我们我们先为解答这道题来了解一些相关的概念吧!
1. 零宽断言
写法 | 名称 | 含义 |
---|---|---|
exp1(?=exp2) | 正向前瞻 | 查找exp2前面的exp1 |
(?<=exp2)exp1 | 负向前瞻 | 查找exp2后面的exp1 |
exp1(?!exp2) | 正向后瞻 | 查找后面不是exp2的exp1 |
(?<!exp2)exp1 | 负向后瞻 | 查找前面不是exp2的exp1 |
Tips: 关于零宽断言的叫法有很多种。本文提到的这几种网上都要涉及到。 下面的正向先行断言就是正向前瞻,是我们解题要用到的。
为了更方便大家理解,举一个例子:
- 正向先行断言(正向零宽断言)
'中国人'.replace(/中(?=国人)/, 'rr')
输出:rr国人
- 反向先行断言
'中国人'.replace(/(?<=中国)人/, 'rr')
输出:中国rr
- 负正向先行断言(负向零宽断言)
'中国人中'.replace(/中(?!国人)/, 'rr')
输出:"中国人rr"
- 负反向先行断言
'中国人中'.replace(/中(?<!国人)/, 'rr')
输出:"rr国人中"
"abZWab863ab88".replace(/(?<![A-Z])ab/g, "")
输出:"ZWab86388"
2.解题思路:
关于腾讯的这道面试题:
如何给一串数字用千分制表示?比如9999999999变成9,999,999,999。要想解答这道题,需要了解以下几个知识点:
- replace与正则约定的特殊标记符$
- 分组语法
1. replace()方法与正则约定的特殊标记符$
写法 | 含义 |
---|---|
$i | (i:1-99),表示从左到右正则子表达式所匹配的文本 |
$& | 表示与正则表达式匹配的全文本 |
$` | `:切换技能键。表示匹配字符串左边的文本 |
? | 表示$转移 |
2. 分组语法:
写法 | 含义 |
---|---|
捕获 | |
(exp) | 匹配exp,并捕获到自动命名到组里 |
(?<name>exp) | 匹配exp,并捕获文本到名称为name到组里 |
(?:exp) | 匹配exp,不捕获匹配的文本 |
位置指定 | |
exp1(?=exp2) | 查找exp2前面的exp1 |
(?<=exp2)exp1 | 查找exp2后面的exp1 |
exp1(?!exp2) | 查找后面不是exp2的exp1 |
(?<!exp2)exp1 | 查找前面不是exp2的exp1 |
注释 | |
(?#comment) | 这种类型的组不对正则表达式对处理产生任何影响,只是为了提供让人阅读注释 |
解析:
- 这里我们采用的是
epx1(?=epx2)
(正向前瞻) - epx1对应的是正则符号是
\d
。
因为第一个逗号之前的数字范围在1-3个之间,所以限定范围\d{1-3}
。 - 然后,exp2对应的是需要限定每3位数字添加一个
,
所以epx2
的正则表达应该是:(\d{3}+$)
(+:出现1次或多次;$:限定以xxx结尾) - 最后,replace()方法第二个参数:使用
$&
符号。$&,
表示捕获与正则表达式匹配的全文本
并置换为,
- 这样写来下就是
'99999999999'.replace(/\d{1,3}(?=(\d{3})+$)/g, '$&,')
接下来:做一道扩展题:
有小数点的'99999999999.02'
做千分之转换,要怎样写呢?
写法一
'99999999999.02'.replace(/\d{1,3}(?=(\d{3})+(?:\.\d+)?$)/g, '$&,')
输出:"99,999,999,999.02"
'99999999999.33333333'.replace(/\d{1,3}(?=(\d{3})+(?:\.\d+)?$)/g, '$&,')
输出:"99,999,999,999.33,333,333"
写法二
正则表达式的写法大多数的时候都不止一种。 千分之表达的另外的一种写法是:
"123456789.12123".replace(/(?!^)(?=(\d{3})+(?:\.\d+)?$)/g, ',')
Tips: 这种写法与之前的写法最大的区别就是:将exp1的部分改为限定字符串的开头不可以添加,
结尾:
谢谢大家阅读,如果觉得对你有帮助,请给作者一点小小的鼓励, 点个赞或者收藏吧。 有需要沟通的请联系我: 微信( wx9456d) 邮箱( allan_liu986@163.com )