#查看是否右边有d,不满足再向后获取一个字符,直到满足右边有字符d;
#剩余字符串dddd再开始查找ab,搜索到字符串结尾,未找到,退出
['c']
>>> re.findall(r'(?<=ab).*(?=d)',s) #贪婪模式,先找到ab,
#再匹配后面所有字符,查看后面有没有d,如果不满足再抛出右面一个字符
#倒退查找后面有没有d,直到找到;剩余字符串d中继续查找ab,不能找到,退出
['cddd']
>>> re.findall(r'(?<=ab).*?',s) #左边有ab,非贪婪模式【先找到ab,后面0个字符,
#满足整个匹配;从剩余的dddd中再次查找,没找到ab,退出】
['']
>>> re.findall(r'(?<=ab).*',s) ##左边有ab,贪婪模式【找到ab,匹配后面整个
#字符串,满足条件;没有剩余字符串,退出】
['cdddd']
>>> re.findall(r'.*(?=d)',s) #先是贪婪模式匹配所有字符,依次倒退找右边是d的
#下次查找位置在本次位置的后面开始,即剩余一个d字符串中找,能够匹配,但匹配的是空串
['aabcddd', '']
>>> re.findall(r'.*?(?=d)',s) #从0个字符串开始,判断后面有没有d,如果没有向右
#取得一个字符继续判断,直到找到d{故第一次aabc};下一次从剩余的dddd找,仍然是从0个字符
#判断,后面有d,返回空串;下次从剩余的ddd中……故四个空串
['aabc', '', '', '', '']
>>> re.findall(r'(d)',s) #单个字符的捕获,有几个d返回共多少个元素的列表
['d', 'd', 'd', 'd']
零宽断言正如它的名字一样,是一种零宽度的匹配,它匹配到的内容不会保存到匹配结果中去,最终匹配结果只是一个位置(并不消耗字符串)。
例子:(?<=一)年(?=半)匹配前面是一和后面是半中的年字
例子:(?<!余)年(?!余) 匹配前面和后面不是余的年字
注意点:
以上量词都是贪婪模式,会尽可能多的匹配,如果要改为非贪婪模式,通过在量词后面跟随一个 ? 来实现
断言不会匹配任何文本,只是对断言所在的文本施加某些约束
前瞻 : exp1(?=exp2) exp1 后面的内容要匹配exp2
负前瞻 : exp1(?!exp2) exp1 后面的内容不能匹配exp2
后顾: (?<=exp2)exp1 exp1 前面的内容要匹配exp2
负后顾 : (?<!exp2)exp1 exp1 前面的内容不能匹配exp2
例如:我们要查找hello,但是hello后面必须是world,正则表达式可以这样写: "(hello)\s+(?=world)" ,用来匹配 "hello wangxing" 和 "hello world" 只能匹配到后者的hello
(?(id)yes_exp|no_exp) :对应id的子表达式如果匹配到内容,则这里匹配yes_exp,否则匹配no_exp