零宽断言的概念可以参考之前的博文
http://cnn237111.blog.51cto.com/2359144/749047
零宽断言,之所以叫零宽,是因为它不消耗字符的,通俗的讲,它不匹配字符串,而是匹配一个位置。比如对于字符串
abcdefg,在正则表达式看来,是下面这个样子的。
p1 a p2 b p3 c p4 d p5 e p6 f p7 g p8 h p9
p1,p2等代表位置,因此8个长度的字符串有9个位置。零宽断言就匹配这些位置。
正则表达式的先行断言和后行断言一共有4种形式:
(?=pattern) 零宽正向先行断言(zero-width positive lookahead assertion)
(?!pattern) 零宽负向先行断言(zero-width negative lookahead assertion)
(?<=pattern) 零宽正向后行断言(zero-width positive lookbehind assertion)
(?<!pattern) 零宽负向后行断言(zero-width negative lookbehind assertion)
正负只是表示相等还是不相等。
比如在字符串
A community is a place where communication and understanding happens中,要匹配后面是字母t,但t后面的必须不是原音字母aeiou的。那么如果写成这种写法:t[^aeiou],那么还是会把t后面的字符也匹配进来。
如果使用零宽断言的话,就可以解决这个问题。
正则表达式t(?=[^aeiou]) 或者t(?![aeiou])都匹配t和一个位置。
那么比如匹配不包含字符串ab的行写法就应该如下:
先写下(?!ab),意思是匹配一个位置,该位置后面没有ab,然后写出(?!ab).,意思就是该位置后面可以跟任何一个字符(除了ab),但这个正则表达式只匹配单个字符,因此该模式匹配某个位置后的单个字符,该字符是a且后面是b,则该字符就得不到匹配。因此对于多个字符只要把该字符分组捕获后加上*即可,因此最终的正则表达式为
((?!ab).)*
如果匹配不包含ab的某一行的话
就是如下写法
^((?!ab).)*$
本文转自cnn23711151CTO博客,原文链接: http://blog.51cto.com/cnn237111/1003376,如需转载请自行联系原作者