javascript正则--零宽断言--案例解析
理解这个案例需要一点点正则基础,要对js的正则有基础的认识与了解,如果没有的话,建议先看完慕课网站的相关js正则课程再来.
下面这个正则要求密码长度最少12位,包含至少1个特殊字符,2个数字,2个大写字母和一些小写字母。
reg=/(?=^.{12,25}$)(?=(?:.?\d){2})(?=.[a-z])(?=(?:.?[A-Z]){2})(?=(?:.?[!@#$%()_+^&}{:;?.]){1})(?!.\s)[0-9a-zA-Z!@#$%()_+^&]$/
看着就很复杂T-T,如果你有一些基础,就应该能认出里面的各个符号的含义.
首先来了解两个概念:
1.正则对象的属性lastIndex
是当前表达式匹配内容的最后一个字符的下一个字符的下标(位置).这个属性的作用非常大,他的主要作用就是回溯标记.
比如在正则有分支的情况下,第一条分支匹配失败,就会回溯到上一个匹配成功的结果的标记处,再尝试匹配其他分支.
比如在使用全局匹配时,第一轮匹配到一个内容,匹配结束,第二轮开始匹配的位置就是从lastIndex开始.
也就是说lastIndex是随着匹配结果变化的
2.零宽断言
本来是叫前瞻(后顾js不支持啦),因为前瞻有个非常重要的特性--即断言匹配时不需要被捕获,不必对应到匹配结果里,只是作为匹配时的条件.而所谓的零宽的真正意义就体现在这里---它工作时不会改变lastIndex属性的值.
现在把两个概念结合一下:捕获性的断言会改变lastIndex属性的值,而零宽断言则不会改变不会改变lastIndex属性的值.理解这一点是理解上面那个例子的关键.
下面开始解析例子
例子里有很多的.*?的组合,我们先从这里开始
. 表示任意字符
*表示可以匹配任意次数
?表示最多匹配一次
三个合起来:对任意个()连续任意字符(.)匹配最多一次(?),也就是说不管有什么字符,不管有没有字符都能被.?匹配上.
以例子里的这一段(?=(?:.?\d){2})为例,
先拆分出(?:.?\d) : 匹配一个数字,不管数字前是什么,也不管数字前有没有都能匹配上.
加上次数(?:.*?\d){2},匹配第二次时从匹配到的第一个数字的下一位开始匹配(lastIndex属性).(这里其实跟零宽断言没什么关系)
再回到整体(?=(?:.*?\d){2}):从第零为开始匹配,至少有两个数字,不管这两数字在什么位置.
这个例子基本上就是几个前瞻组成的,零宽断言表示的只是匹配的位置,由于前瞻的前面没有用字符提出匹配内容,所以例子里的每一个前瞻都是从字符串最开始的地方开始匹配.
例子里的其他部分解释起来与(?=(?:.?\d){2})大同小异,理解了(?=(?:.?\d){2}),同样的道理往其他几个上一套,整体就出来了
共同学习,写下你的评论
评论加载中...
作者其他优质文章