转自:https://blog.csdn.net/qq_42739440/article/details/81117919

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

例题:

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

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

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

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

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

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

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

findall函数的源码解析

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

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

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

白话理解:

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

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

例题解答:

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

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

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

05-11 16:59