携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情
前言
正则表达式匹配密码可以说是最常见的需求了,虽然各个项目对于密码的要求不一,但是其实有相通的地方。
比如,规定了密码的长度,密码必须包含哪些字符,不能包含哪些字符,可以包含哪些字符等等。
本文来记叙这些需求的处理做法。
必须包含的字符
按照匹配密码的顺序来讲,需要先解决相对比较难的点,就是怎么确定密码是否带有必须包含的字符,比如,密码必须得要包含数字才行。
一般这种需求都是使用预查的方式,不管使用的是正向肯定预查或者负向肯定预查都好,就是通过预查,能保证字符串含有指定的字符。
按照上面的必须包含数字的需求,可以写出如下的表达式:
const reg = /(?=[0-9])/
可以看到,通过预查,得到了数字的起始位置,也就表明了密码中含有数字;如果匹配不到相应的位置,也就说明密码中不包含数字。
这里有一个需要注意的要点,那就通过预查匹配到的位置必须在字符串开头,这样可以方便后续对整个密码的长度和数据格式进行校验。
不然会添加很多工作量。
如果在测试的数据前面加上其他字符,会出现如下情况:
在测试数据前面加上英文字母,会发现,通过预查匹配的数字的位置不是在字符串的开头,这显然会妨碍后续的处理,怎么把预查匹配到的位置放在密码开头呢?
其实也很简单,只要在匹配数字的前面加上匹配任意数量的任意字符即可,也就是不论数字前面是什么,都是符合要求的:
const reg = /(?=.*[0-9])/
再次匹配到了字符串的开头,如果字符串中没有数字,就不会匹配到任何位置:
其他必须包含的字符也是这样的处理,只要逐个加上即可,比如除了数字,还必须包含英文字母,接着加上英文字母的预查即可:
const reg = /(?=.*[0-9])(?=.*[A-Za-z])/
可以看到,必须同时包含数字和英文字母才能找到字符串开头的位置。
可以包含和不能包含
可以包含 和 不能包含 其实是一个需求,就是字符串可以包含哪些字符而已,那些没被包含就是不能包含的,不会被正则表达式匹配到,一旦出现,正则表达式就匹配不了。
比如说,现在密码除了必须包含数字和英文字母外,还可以包含 *、/、+、-这四个特殊字符,但不能包含其他特殊字符。
这就需要匹配字符串了,通过上面对位置的匹配,已经实现了必须包含数字和英文字母的需求,并且匹配到位置是在字符串的开头。
这回只需要从头到尾,对每一个字符进行检查,确保其符合数字、英文字母或者是 *、/、+、-这四个特殊字符即可,应该使用 [0-9a-zA-Z\*\-\+\/]+ 进行匹配:
const reg = /^(?=.*[0-9])(?=.*[A-Za-z])[0-9a-zA-Z\*\-\+\/]+$/
在上面的测试中,即使字符串没有包含 *、/、+、-这四个特殊字符,也是可以匹配的,加上这个四个特殊字符也是可匹配的。
但是,加上了指定外的字符 # ,正则表达式就匹配不了了。
长度
这个直接使用 {x, x} 进行限制即可,不再赘述,比如限制密码长度在 6 ~ 8位:
const reg = /^(?=.*[0-9])(?=.*[A-Za-z])[0-9a-zA-Z\*\-\+\/]{6, 8}$/