本文正在参加「金石计划 . 瓜分6万现金大奖」
正则表达式 (实战案例)🛫
前言
推荐先阅读
再阅读本文。
本文主要通过各种 正则表达式 的 项目实战案例,来确保彻底搞懂!
1. 手机号匹配
对于匹配手机号,可算是学完 正则表达式,就想上手试试的案例,它也是经典的案例,经常在输入框中的需求中遇到过
功能点拆解分析:
-
手机号总共
11位数字 -
并且 第一位 必须是数字
1 -
第二位,则是数字
3-9中的,任意一个
正则表达式:
const reg = /^1[3-9]\d{9}$/g
正则分析:
-
由于第一位是
1,则用^1来表示 -
第二位
3-9则用 区间[3-9]来表示 -
剩下的就是
11-2=9,剩余的9位数字,\d代表数字,重复使用{9}来处理
知识点:
-
元字符 的 开头
^、 结尾$、数字\d -
区间 的
[] -
重复 的
{}
2. 手机号中间四位,用 * 替换
这个需求是基于上面的,我们在 输入层 做了限制之后。
我们就需要在列表中进行展示 手机号
而这个需求的 目的就是为了进行 手机号的 私密保护。
功能点拆解分析:
-
首先手机号是
11位,这是确定的 -
将中间
4位进行加密,也就是第4个数字,到 第7个数字,将其变成*,其余的不动
正则表达式:
const str = '13008828889'
const reg = /^(\d{3})(\d{4})(\d+)/
const newStr = str.replace(reg, ($0, $1, $2, $3) => {
return `${$1}****${$3}`
})
正则分析:
-
既然是替换,那肯定离不开
string的replace方法 -
通过上面的分析,可以分成
3组,-
第一组是 前三位
\d{3} -
第二组是 中间四位
\d{4} -
第三组是 最后四位
\d{4}或者\d+都可以
-
这部分是很简单的,接下来说一下 replace 方法
对于 正则的情况下
-
$0代表的是 字符串 本身 -
$1代表的是 第一个分组 -
$2代表的是 第二个分组 -
$3代表的是 第三个分组
最后进行组装返回即可
不过这里你可能会有疑问,为什么不用 args
知识点:
-
元字符 的 开头
^ -
重复 的
+和{} -
分组 的
() -
String的replace方法
3. 体温
现在疫情原因,很多地方需要量体温,而此时的这个需要登记当前这个人的体温度数,会将输入框做一些限制
功能点拆解分析:
-
正常情况下,能登记温度的,那就是
35度以上,42度以下 -
可以输入小数点,但是出现小数点后,则小数点后,必须跟上一位有效数字(即 非0)
正则表达式:
const reg = /(^((3[5-9])|(4[0-1]))((\.)[1-9])?$)|(^42$)/g
正则分析:
由于可以输入一位小数,所以这个需求其实难度已经上来了
话不多说,直接分析
第一步: 先根据 数字 后面,能否跟上小数点进行分组
-
没有小数点的,仅仅只有
42这一个数字,通过(^42$)表示即可 -
有小数点的,则拥有
35到41.9
第二步: 在能够产生小数点的数字之中,进行区分是否存在小数点
-
若 存在 小数点,则小数点后必须有数字,且 非0,
(\.)[1-9] -
若 不存在 小数点,则在上面的基础上,添加重复字符
?,来表示 存在0次或者1次 -
最终这段写法为
((\.)[1-9])?$
第三步: 判断开始的值
-
当开始为
3,则后面只能跟上 区间5-9,通过(3[5-9])表示 -
当开始为
4,则后面只能跟上 区间0-1,通过(4[0-1])表示
它们组合起来,就是最终 体温 的 正则表达式
知识点:
-
元字符 的 开头
^、 结尾$ -
区间 的
[] -
重复 的
? -
分组 的
()以及 或字符符| -
转义 的
\
4. 格式化 数字
有这么一个场景,给你字符串,里面是数字,而你必须展示 数字 的小数点后两位 ,如果后面没有则补充 0
例如:
-
给
81,但是你需要展示81.00 -
给
77.1,展示77.10 -
给
66.22,则不变
你可能直接说,将其转成数字,然后 toFixed 下结束了,那我要是说
-
那我要是需求改成,没有则补充
x字符,你要怎么做-
当然一般情况下,不会有这种极端需求滴,哈哈哈哈😂
-
这个例子,主要是为了下面的例子🎁 来做铺垫!
功能点拆解分析:
-
首先判断是否存在
.字符-
没有,则直接补充即可
-
有,则通过 正则表达式 判断点后面是否只跟上了一位数字
-
正则表达式:
const reg = /\d+\.\d$/
const arr = ['80', '44', '0.91', '99', '19.1', '3.1', '5.2']
const newArr = arr.map((item) => {
if (item.indexOf('.') === -1) {
return `${item}.00`
} else {
const newStr = item.replace(reg, (args) => {
return `${args}0`
})
return newStr
}
})
正则分析:
我们这边直接看 存在 小数点的,因为这里面用到了 正则表达式
-
首先前面肯定是数字,那么
\d表示,并且数字的字符个数是大于1的,所以用+表示 -
其次是遇到
.字符,将其通过\进行转义 -
最后小数点后有一位,则用
\d$结尾 即可
之后我们会通过 replace 方法,来进行数据替换
args代表匹配到的值
知识点:
-
元字符 的 结尾
$、数字\d -
重复 的
+ -
转义 的
\ -
replace方法
5. 格式化 金额
在上面的例子基础上,这个是经典的,格式化我们的数字金额的操作
下面看下如何处理
功能点拆解分析:
-
正常情况下,我们拿到的是数字,但是想要通过正则来处理的话,我们需要将
number类型的数字,转成string字符串 类型 -
在字符串状态下,判断是否存在小数点
-
没有小数点,则从最后一个字符开始,往前走遇到
3个字符,在前面添加一个,,依次类推 -
有小数点,则从小数点前面的字符开始,往前走遇到
3个字符,在前面添加一个,,依次类推
可以看到,其实我们先确认结尾,之后向前进行判断。
-
正则表达式:
const str = '12987654321.12'
const reg = /(\d)(?=(\d{3})+($|\.))/g
const newStr = str.replace(reg, (args) => {
console.log(args, 'args')
return `${args},`
})
console.log(newStr, 'newStr')
正则分析:
-
首先确认结尾,则用
$或者 出现.来当结尾,则结尾表达式为$|\. -
最开始前面一定要有 数字,所以用
\d表示 -
在数字后面,通过 正向先行断言,去进行判断,是否是连着3个数字,并且末尾是
$|\.的字符-
在这个过程中,会从左到右判断,成功的字符,将会被匹配出来
-
之后通过
replace方法,将匹配出来的字符,进行更换
-
知识点:
-
元字符 的 结尾
$ -
重复 的
{}和+ -
分组 的
()以及 或字符符| -
转义 的
\ -
断言 的 正向先行断言
(?=)
6.密码强度
现在很多网站,我们再注册时,它都能显示你目前的密码强度是 弱,中强,强
它是如何判断的呢?
- 大部分都是通过正则来判断
我们这里也给出这个例子,让其输入的密码,必须包括
-
数字,大写字母,小写字母,特殊字符
-
长度在
8~16位之间
功能点拆解分析:
-
数字
\d -
大写字母
[A-Z] -
小写字母
[a-z] -
特殊字符
[~!@#$%^&_+-*/\.] -
8~16位
{8,16}
正则表达式:
简单方式
上面已经给出了 相关的 正则表达式
其实我们可以写 四次 test 来进行判断
-
但是要注意的是,
test之后要进行 恢复操作 -
即
RegExp.lastIndex = 0的操作。
不然的话,你就能看见 快乐的bug 出现了🤣
这里就不讲解了,感兴趣的去搜索 js 正则 test 方法 bug
复杂方式
我们着重分析 复杂方式,其实只需要一行
通过 正向先行断言 来进行处理
const reg = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[~!@#$%^&_+\-*/.])([0-9a-zA-Z~!@#$%^&_+\-*/.]){8,16}$/g
正则分析:
先看到后面有一个 分组,里面是一个 区间
- 区间里面的内容为所有可以写入的字符:
[0-9a-zA-Z~!@#$%^&_+\-*/.]
最后通过 重复 的 {8,16} 来表示
如果直接显示这个,是不行的
-
因为 区间 中,是 只要匹配到一个即可成功,
-
所有 这个只能保证我们输入的字符是这些中的任意一个
-
并不能做到根本的限制
所以我们看到前面有 四个 正向先行断言 ,我们来分析下
-
第一个: 断言 里面肯定有 数字
-
第二个: 断言 里面肯定有 小写字母
-
第三个: 断言 里面肯定有 大写字母
-
第四个: 断言 里面肯定有 特殊字符
所以这些组合起来,就可以做到 密码强度 的校验
知识点:
-
元字符 的 开头
^,结尾$,.匹配任意字符,\d匹配数字 -
重复 的
{}和* -
分组 的
() -
区间 的
[] -
转义 的
\ -
断言 的 正向先行断言
(?=)