零宽负向先行断言(?!exp),只会匹配后缀exp不存在的位置。d{3}(?!d)匹配三位数字,而且这三位数字的后面不能是数字。
同理,我们可以用(?<!exp),零宽负向后行断言来查找前缀exp不存在的位置:(?<![a-z])d{7}匹配前面不是小写字母的七位数字(实验时发现错误?注重你的“区分大小写”先项是否选中)。
一个更复杂的例子:(?<=<(w )>).*(?=</1>)匹配不包含属性的简单HTML标签内里的内容。(<?(w )>)指定了这样的前缀:被尖括号括起来的单词(比如可能是<b>),然后是.*(任意的字符串),最后是一个后缀(?=</1>)。注重后缀里的/,它用到了前面提过的字符转义;1则是一个反向引用,引用的正是捕捉的第一组,前面的(w )匹配的内容,这样假如前缀实际上是<b>的话,后缀就是</b>了。整个表达式匹配的是<b>和</b>之间的内容(再次提醒,不包括前缀和后缀本身)。
小括号的另一种用途是能过语法(?#comment)来包含注释。例如:2[0-4]d(?#200-249)|25[0-5](?#250-255)|[01]?dd?(?#0-199)。
要包含注释的话,最好是启用“忽略模式里的空白符”选项,这样在编写表达式时能任意的添加空格,Tab,换行,而实际使用时这些都将被忽略。启用这个选项后,在#后面到这一行结束的所有文本都将被当成注释忽略掉。
例如,我们可以前面的一个表达式写成这样:
(?<= # 查找前缀,但不包含它
<(w )> # 查找尖括号括起来的字母或数字(标签)
) # 前缀结束
.* # 匹配任意文本
(?= # 查找后缀,但不包含它
</1> # 查找尖括号括起来的内容:前面是一个"/",后面是先前捕捉的标签
) # 后缀结束
当正则表达式中包含能接受重复的限定符(指定数量的代码,例如*,{5,12}等)时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配
评论加载中…
![]() |