最近看完了《精通正则表达式》的前面和语言无关的几章,也正好碰到了一个知乎问题,所以就强行答了一下。如何理解先行断言
把我的回答再总结一下。 (?=)在《精通正则表达式》书上叫“环视”,具体上说叫“顺序肯定环视”。环视不占有字符,只作为判断的条件进行匹配。
1,具体如下这个例子
^(?=.*\d)(?=.*[A-Z])\w{8,15}$
先来刨去两个(?=)环视条件
^\w{8,15}$
这个很好理解,即^匹配初试位置锚点,\w匹配各种文字字符(我理解就是字母数字文字等),{8,15}前面字符\w的数量8-15个,最后$是末位置锚点。整体上就是匹配一个从初始到结束为8-15位全文字字符的字符串。
现在加上(?=)
第一个(?=.\d),括号位置在^之后,表示从初始锚点这个位置开始匹配,.匹配各种字符直到末位,后跟\d表示匹配数字,这时需要回溯寻找为数字的位置,如果回溯到有数字的位置,那么匹配成功。所以这个环视表达式的意思是,如果从锚点的位置后面有含数字的字符则匹配成功,满足条件,否则不满足。
那么第二个也是同样道理,(?=.*[A-Z]),表示如果从初始锚点位置后面存在大写字母字符,则匹配成功,满足条件。这里注意一下,环视不占有字符,所以,即使这个环视表达式在后面,也同样是在其位置^之后开始匹配检查。
最后把两个环视条件都加上,整个表达式的意思就是一个从初始到结束为8-15位的全文字字符且必须含有至少一个数字字符和至少一个大写字母字符的字符串。
2,(?=...)环视表达式如何理解
我个人理解就是把这个看成一个条件表达式,是整体匹配成功的必须要满足的条件。
(?=...)为顺序肯定环视,其他三个环视意思类似。这个表达式从括号的所在的匹配位置开始进行匹配判断,并且不占用匹配字符,即,括号后面的匹配位置不变。
看完这本正则书后,虽然很多特定的匹配符号和字符没有完全能够记住,但是从比较深层次的角度来理解正则表达式的匹配过程,了解正则逐字符的匹配过程,回溯等过程。感觉这样对于思考和分析整个正则表达式的细节非常有帮助。