现在有一个匹配问题,匹配密码,必须包含大写,小写和数字,和特殊字符(!,@,#,%,&),且大于6位。
先看明白要匹配的条件,必须包含大写、小写、数字和特殊字符,但是出现的顺序没有规定,只要包含有就行,一般的正则表达式都是按顺序来进行匹配的,所以有什么办法可以解决这个没有顺序的匹配呢,或者说有什么匹配机制可以每次匹配完,又重新从头开始进行下一次匹配呢?前瞻就可以。
1.前瞻表达式
在正则表达式当中有个东西叫做前瞻,有的管它叫零宽断言:
表达式 | 名称 | 描述 |
---|---|---|
(?=exp) | 正向前瞻 | 匹配后面满足表达式exp的位置 |
(?!exp) | 负向前瞻 | 匹配后面不满足表达式exp的位置 |
我们来看看前瞻的作用:
var str = 'Hello, Hi, I am Hilary.'; // 后面一定要匹配什么 var reg = /H(?=i)/g; var newStr = str.replace(reg, "T"); console.log(newStr);//Hello, Ti, I am Tilary.
在这个DEMO中我们可以看出正向前瞻的作用,同样是字符"H",但是只匹配"H"后面紧跟"i"的"H"。就相当于有一家公司reg,这时候有多名"H"人员前来应聘,但是reg公司提出了一个硬条件是必须掌握"i"这项技能,所以"Hello"就自然的被淘汰掉了。
以上内容摘至 : https://www.cnblogs.com/dong-xu/p/6926064.html
2.前瞻表达式每次进行匹配lastIndex(查找的起点 )都为0
如果是普通的正则表达式,且匹配模式是全局匹配(global),lastIndex匹配结果如下:
var str = 'aaaAAA'
var reg = /(.*[A-Z])/g
console.log(reg.lastIndex); // 输出 0
console.log(reg.exec(str)); // 简写就是匹配为 [aaaAAA]
console.log(reg.lastIndex); // 输出6 表示下次匹配从下标6开始
如果是前瞻表达式,lastIndex匹配结果如下:
var str = 'aaaAAA'
var reg = /(?=.*[A-Z])/g
console.log(reg.lastIndex); // 输出 0
console.log(reg.exec(str)); // 简写就是匹配到 [''] 即匹配到aaaAAA的前面位置,是空的
console.log(reg.lastIndex); // 输出0 表示下次匹配从下标0开始
所以说用前瞻表达式进行匹配,每次都是从头开始的。(不论匹配模式是否是全局匹配 global),
我们可以利用这个特性来进行没有顺序的匹配。
3.密码匹配问题(匹配密码,必须包含大写,小写和数字,和特殊字符(!,@,#,%,&),且大于6位。)
有了上面的基础,就可以进行密码匹配了,我们先效验密码必须包含大写、小写、数字和特殊字符:
var reg = /(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[!@#%&])/g
//因为大写、小写、数字、特殊字符出现的位置未知
//所以要在每个表达式前加上 .* 表示前面可能有内容,可能没有内容
//用前瞻只是为了它会重新开始的机制,并不用它匹配到的前面的内容
然后上面条件满足了就可以限制其次数:
var reg = /^[A-Za-z\d!@#%&]{6,}$/g
最后可以把两个正则表达式合在一起就可以进行密码匹配
var str = '@GGA3124a3523'
var reg = /(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[!@#%&])^[A-Za-z\d!@#%&]{6,}$/g
console.log(reg.test(str)); // true