正则表达式——断言补充
4.4 补充
4.4.1 环视的价值
环视有一个很重要的玉兔,就是避免编写正则表达式“牵一发动全身”的尴尬——既可以集中关注某个地方,添加全局性的限制,又不会干扰其他部分的匹配。有些时候,为进行全局性限制而真正匹配文本,会让情况变复杂。
4.4.2 环视与分组编号
环视结构也要用到括号,这种括号是否会影响到分组编号呢?
前面说过,分组的编号只与捕获型号有关,而不受其他任何类型括号的影响。所以,环视结构虽然出现了括号,但并不影响分组。注:环视结
4.4.3 环视的支持程度
php
PHP 对逆序环视中表达式中的限制要宽松一点,它能匹配文本的长度可以不必限定,但是长度必须是确定的数值:(?<=dog|cats)
是没有问题,因为两个分支的长度都是固定的;而(?<!dogs?|cats?)
则有问题,因为两个分支的长度都是不确定的。
4.4.4 环视的组合
环视匹配的并不是字符,而是位置。在正则表达式匹配时,环视结构匹配成功,并不会更改“当前位置”,所以多个环视可以组合在一起,实现在同一个位置的多重判断。
- 环视中包含环视
- 并列多个环视
- 环视作为多选分支
4.4.5 断言和反向引用之间的关系
断言不匹配任何字符,只匹配位置;而反向引用只引用之前的捕获分组匹配的文本,之前捕获行分组中瞄点表示的位置信息,在反向引用时并不会保留下来。
举例来说,如何表达式是(\bcat\b)\s+\1
,\1
所匹配的,就不知有单独出现的cat
,还包括单词内部的cat
(比如cate
中的cat
),如果要验证单词cat
是否在字符串中出现了两次,正确的做法是在反向引用两端也加上单词边界\b
,变成(\bcat\b).*?\1\b
。