且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

正则表达式匹配不包含特殊子串的字符串(零宽断言的使用)

更新时间:2022-09-26 22:27:53

零宽断言的概念可以参考之前的博文

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,如需转载请自行联系原作者