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).)*(编程|学习).*$'