初步理解正则表达式中的Lookaround

7/18/2010来源:C#应用人气:6634

正则表达式中有Lookahead and Lookbehind一说,可以统称为Lookaround。
Lookahead包含:(?=)、(?!)
Lookbehind包含:(?<=)、(?<!)
可以看出它们俩都包含了正负,即"="与"!"
Lookbehind中多了个"<",为了便于记忆,可以把"<"形象地看成"向左看"!
同样,为了便于记忆,可以认为:ahead是向右看,behind是向左看。

 

为了便于理解,先撇开Lookaround,进行匹配,然后再考虑它。
例如:(?<=ab)cd,我就先把它看成:cd,然后再考虑(?<=ab)

 

如果,我有一个正则表达式:(?<=ab)cd,判断它能否匹配abcd、efcd。
这是一个Lookbehind,我先考虑cd,显然cd都可以匹配abcd、efcd,但是当我再考虑(?<=ab)时,只有abcd能够被匹配了,因为在abcd中的cd前面有ab,但是efcd中的cd前面没有ab。

 

同样,我可以分析:ab(?=cd),能否匹配abcd、abef。
这是一个Lookahead,我先考虑ab,显然ab都可以匹配abcd、abef,但是当我再考虑(?=cd)时,只有abcd能够被匹配了,因为在abcd中的ab后面有cd,但是abef中的ab后面没有cd。

 

实际上,无论是Lookahead还是Lookbehind都是,从左到右进行匹配的。
Lookahead可以像上面那样理解;
Lookbehind其实是,先到左边看看,是否满足,再匹配的。但是,也可以像上面那样理解。

 

经过上述介绍,大家可能就思维定势了,认为Lookbehind都在左边,而Lookahead都是在右边。
如果要我运用Lookaround来,判断一个单词是否以s结尾/开头,可能首先就会写出:

\b\w+(?=s)\b        //以s结尾\b(?<=s)\w+\b       //以s开头
 

 

不幸的是,上面两个都是错的!千万不要有思维定势,正确的是这样的:

\b\w+(?<=s)\b       //以s结尾\b\w+(?<!s)\b       //不以s结尾\b(?=s)\w+\b        //以s开头\b(?!s)\w+\b        //不以s开头
 

 

借助于Lookaround可以写出具有组合功能的正则表达式。
如果,你想匹配一个单词,它满足:

1.长度为4-62.包含oo3.不以s结尾
 

可以用这样的正则表达式来搞定:

\b(?=\w{4,6}\b)\w*oo\w*(?<!s)\b
 

它可以匹配:zooz、ooooo、xxoo等
但是不匹配:xoo、zoos、ooooooo等

 

 

如发现错误之处,请大家指出!

如有更好的理解方式,请共享!

谢谢!