零宽断言是正则表达式中的一种方法,正则表达式在计算机科学中,是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。本文主要是介绍Python中,使用正则表达式的零宽正负向断言的方法,和使用零宽断言来解决包含某个字符串且不包含某字符串的问题,以及相关示例代码。

1、零宽断言表达式

(?=exp):零宽度正先行断言。仅当子表达式 exp 在此位置的右侧匹配时才继续匹配。例如,/w+(?=/d) 与后跟数字的单词匹配,而不与该数字匹配。此构造不会回溯。

(?!exp):零宽度负先行断言。仅当子表达式 exp 不在此位置的右侧匹配时才继续匹配。例如,/w+(?!/d) 与后不跟数字的单词匹配,而不与该数字匹配 。

(?<=exp):零宽度正后发断言。仅当子表达式 exp 在此位置的左侧匹配时才继续匹配。例如,(?<=19)99 与跟在 19 后面的 99 的实例匹配。此构造不会回溯。

(?<!exp):零宽度负后发断言。仅当子表达式 exp 不在此位置的左侧匹配时才继续匹配。例如,(?<!19)99 与不跟在 19 后面的 99 的实例匹配

2、使用示例代码

1)(?=exp)

s = "I'm singing while you're dancing."
p = re.compile(r'\b\w+(?=ing\b)')
print '【Output】'
print re.findall(p,s)
【Output】
['sing', 'danc']

2) (?<=exp)

s = "doing done do todo"
p = re.compile(r'(?<=\bdo)\w+\b')
print '【Output】'
print re.findall(p,s)
【Output】
['ing', 'ne']

3) (?!exp)

s = 'done run going'
p = re.compile(r'\b\w{2}(?!ing\b)')
print '【Output】'
print re.findall(p,s)
【Output】
['do', 'ru']

注意:负向断言不支持匹配不定长的表达式

4)(?<!exp)

s = 'done run going'
p = re.compile(r'(?<!\bdo)\w{2}\b')
print '【Output】'
print re.findall(p,s)
【Output】
['un', 'ng']

注意:负向断言不支持匹配不定长的表达式

3、使用零宽断言判断包含某个字符串且不包含某字符串

判断字符串后边包含"编程"或"学习"字符串,前边不能包含cjavapy字符串,使用零宽断言示例如下:

#coding=utf-8
import re
pattern = '^((?<!cjavapy).)*(编程|学习).*$'
w = '今年线上cjavapy开始网上编程知识收集'
#w = '今年线上开始网上编程知识收集'
result = re.search(pattern, w)
print(result)

4、使用零宽断言表达式与正则表达式.*组合使用写法

上述示例中代码,可能错误写成如下:

pattern = '^.*(?<!cjavapy).*(编程|学习).*$'

当.*和零宽断言表达式组合时,应该注意与任意字符.的组合,如下:

pattern = '^((?<!cjavapy).)*(编程|学习).*$'

推荐文档