Python中正则匹配使用findall,捕获分组(xxx)和非捕获分组(?:xxx)的差异

版权声明: https://blog.csdn.net/qq_42739440/article/details/81117919

下面是我在用findall匹配字符串时遇到的一个坑,分享出来供大家跳坑。

例题:

# 请匹配出以下字符串中所有的邮箱:
str1 = "123@qq.comaaa@163.combbb@126.comasdf111@asdfcom"

如图所示: 正则a和正则b两个式子匹配出来的结果是不同的。

那 ?: 的作用就是把捕获分组转变为非捕获分组。

什么是捕获组和非捕获组呢?

(qq|163|126) ---> 这样单独的括号就为捕获组

(?:qq|163|126) ---> 这样在原有分组里加上?: 就把捕获组转变为一个非捕获组

findall函数的源码解析

在这里面大家可以看一下findall函数的源码解析,用help(re.findall) 查看,得到如下翻译:

finall(模式,字符串,标记=0)
    返回字符串中所有非重叠匹配的列表。
    如果模式中存在一个或多个捕获组,则返回一个组列表;如果模式有多个组,这将是一个元组列表。
    结果中包含空匹配项。

白话理解:

findall函数,就是说在正则匹配里,如果有分组,就仅仅匹配分组里面的内容,然后返回这个组的列表; 如果有多个分组,那就把每一个分组看成一个单位,组合为一个元组,然后返回一个含有多个元组的列表。

例题解答:

区别了捕获组和非捕获组后,上面开头例题中匹配邮箱的问题就迎刃而解了。

正则a的式子:r"\w+@(qq|163|126).com" 是匹配了捕获组,所以得到了['qq', '163', '126'] 这个列表;

正则b的式子: r"\w+@(?:qq|163|126).com" ,?: 把捕获组转变为一个非捕获组,使得这个式子可以从头到尾全部匹配,所以成功得到了 ['123@qq.com', 'aaa@163.com', 'bbb@126.com'] 这个邮箱列表。

展开阅读全文

没有更多推荐了,返回首页