介绍:
零宽断言用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像 \b ^ $ \< \> 这样的锚定作用,用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。
断言用来声明一个应该为真的事实。正则表达式中只有当断言为真时才会继续进行匹配。
1.零宽度正预测先行断言 (?=exp) 匹配exp前面的位置
例:[a-z]*(?=ing) 可以匹配 cooking 和 singing 中的 cook 与 sing 。
注意:先行断言的执行步骤是这样的先从要匹配的字符串中的最右端找到第一个 ing (也就是先行断言中的表达式)然后 再匹配其前面的表达式,
若无法匹配则继续查找第二个 ing 再匹配第二个 ing 前面的字符串,若能匹配则匹配,符合正则的贪婪性。
2.零宽度正回顾后发断言
(?<=exp) 匹配exp后面的位置
例:.*(?=ing) 可以匹配 "cooking singing" 中的 "cooking sing" 而不是 cook
注意:后发断言跟先行断言恰恰相反 它的执行步骤是这样的:先从要匹配的字符串中的最左端找到第一个abc(也就是先行断言中的表达式)然后
再匹配其后面的表达式,若无法匹配则继续查找第二个 abc 再匹配第二个 abc 后面的字符串,若能匹配则匹配。
例:(?<=abc).* 可以匹配 abcdefgabc 中的 defgabc 而不是 abcdefg
3.零宽度负预测先行断言
(?!exp) 匹配后面跟的不是exp的位置
例:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字
4.零宽度负回顾后发断言 (?<!exp) 匹配前面不是exp的位置
例:(?<![a-z])\d{7}匹配前面不是小写字母的七位数字。
实例:
例1:\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。
例2:(?<=\bre)\w+\b 匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。
例3:(?<=\s)\d+(?=\s) 匹配以空白符间隔的数字(再次强调,不包括这些空白符)。
例4:((?<=\d)\d{3})+\b,用它对1234567890进行查找时结果是234567890。
例5:\b\w*q(?!u)\w*\b 匹配包含后面不是字母u的字母q的单词
例6:\d{3}(?!\d) 匹配三位数字,而且这三位数字的后面不能是数字
例7:\b((?!abc)\w)+\b 匹配不包含连续字符串abc的单词。
参考出处
《正则表达式30分钟入门教程》http://deerchao.net/tutorials/regex/regex.htm#negativelookaround
《零宽断言》http://www.ha97.com/book/OpenSource_Guide/ch26s09.html
《perl中的正则表达式》http://bbs.chinaunix.net/forum.PHP?mod=viewthread&tid=159388