转自:https://blog.csdn.net/qq_42739440/article/details/81117919
下面是我在用findall匹配字符串时遇到的一个坑,分享出来供大家跳坑。
例题:
如图所示: 正则a和正则b两个式子匹配出来的结果是不同的。
那 ?:
的作用就是把捕获分组转变为非捕获分组。
什么是捕获组和非捕获组呢?
(qq|163|126) ---> 这样单独的括号就为捕获组
(?:qq|163|126) ---> 这样在原有分组里加上?:
就把捕获组转变为一个非捕获组
findall函数的源码解析
在这里面大家可以看一下findall函数的源码解析,用help(re.findall)
查看,得到如下翻译:
白话理解:
findall函数,就是说在正则匹配里,如果有分组,就仅仅匹配分组里面的内容,然后返回这个组的列表; 如果有多个分组,那就把每一个分组看成一个单位,组合为一个元组,然后返回一个含有多个元组的列表。
例题解答:
区别了捕获组和非捕获组后,上面开头例题中匹配邮箱的问题就迎刃而解了。
正则a的式子:r"\w+@(qq|163|126).com" 是匹配了捕获组,所以得到了['qq', '163', '126'] 这个列表;
正则b的式子: r"\w+@(?:qq|163|126).com" ,?: 把捕获组转变为一个非捕获组,使得这个式子可以从头到尾全部匹配,所以成功得到了 ['[email protected]', '[email protected]', '[email protected]'] 这个邮箱列表。