Python中正则匹配使用findall时的注意事项

在使用正则搜索内容时遇到一个小坑,百度搜了一下,遇到这个坑的还不少,特此记录一下。

比如说有一个字符串  "[email protected]@[email protected]@asdfcom"

想匹配出里面所有的邮箱地址,该怎么实现呢?

写了个正则,测试一下:

>>> import re
>>> s  = "[email protected]@[email protected]@asdfcom"
>>> pattern1 = "\[email protected](qq|163|126)\.com"
>>> m1 = re.search(pattern1,s)
>>> m1.group()
‘[email protected]‘

可以看到,能够正确搜索到第一个结果,正则写得没问题,如果我想得到所有结果,自然而然就想到了用findall()方法。来试试看:

>>> m2 = re.findall(pattern1,s)
>>> m2
[‘qq‘, ‘163‘, ‘126‘]

这时候估计很多人就觉得奇怪了,使用search方法能搜索到,说明正则写得没问题呀,为什么使用findall的时候结果是这个样子的?为什么结果不是整个邮箱字符串?

查了资料才清楚一个概念,叫做捕获分组

简单说,就是正则表示式里出现括号的时候,括号里的内容匹配到的部分是会被作为结果输出的,而不是把整个正则表达式匹配到的内容作为结果输出。

所以,就出现了上面的结果了。

那怎么得到想要的结果呢?在Python里,当一个分组的头部出现"?:"时,表示这是一个非捕获分组,意思就是它只是正常参与匹配过程,但不作为独立的结果进行输出。

那么按这个写法来试试:

>>> pattern2 = "\[email protected](?:qq|163|126)\.com"
>>> m2 = re.findall(pattern2,s)
>>> m2
[‘[email protected]‘, ‘[email protected]‘, ‘[email protected]‘]

取消了这个捕获分组,那么就是把整个表达式作为一个结果输出,这样才是我们预期想要的效果。

这种情况在使用正则中的“或”匹配时是特别需要注意的,因为这时候通常会加括号,很多初学者很容易掉进这个坑,得到一个不知所谓的结果。

当然,捕获分组这个功能本来是正常有用的,只是要用对了才行。

比如,同样是刚才这个例子,如果只想要邮箱中的用户名部分,该怎么写正则表达式呢?

显然就是把用户名部分加括号作为一个捕获分组就可以了。

>>> pattern3 = "(\w+)@(?:qq|163|126)\.com"
>>> m3 = re.findall(pattern3,s)
>>> m3
[‘123‘, ‘aaa‘, ‘bbb‘]

对于findall()函数,其帮助是这么说明的:

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

分组这个功能还是比较强大的,以后会继续学习更多的部分。

参考文章:https://blog.csdn.net/qq_42739440/article/details/81117919

原文地址:https://www.cnblogs.com/achillis/p/10353963.html

时间: 2024-10-11 06:30:14

Python中正则匹配使用findall时的注意事项的相关文章

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

转自:https://blog.csdn.net/qq_42739440/article/details/81117919 下面是我在用findall匹配字符串时遇到的一个坑,分享出来供大家跳坑. 例题: 如图所示: 正则a和正则b两个式子匹配出来的结果是不同的. 那 ?: 的作用就是把捕获分组转变为非捕获分组. 什么是捕获组和非捕获组呢? (qq|163|126) ---> 这样单独的括号就为捕获组 (?:qq|163|126) ---> 这样在原有分组里加上?: 就把捕获组转变为一个非捕获

python中正则匹配字符\b配置单词边界不生效的解决办法

#-*-coding:utf-8-*-import rename="duoceshi"p= re.compile('\bduoceshi\b')f = p.search(name)if f:    print f.group()########################################3p= re.compile(R'\bduoceshi\b')  #这里要加上原始字符r/R,原因是:python默认会把\b解码给ascii码8(退格符)f = p.search(

关于php中正则匹配包括换行符在内的任意字符的问题总结

要使用正则匹配任意字符的话,通常有以下几种方法,这里我分别对每一种方法在使用的过程中做一个总结: 第一种方式:[.\n]*? 示例 ? PHP preg_match_all('/<div class="list">[.\n]*?<\/div>/i', $content, $data); 按道理这种方式应该是可以的,但我测试发现不行,因为这里中括号里面的“.”被当作一个普通的英文句号去处理了,而不是通配符,因此这里只能匹配到包含英语句号及换行符在内的任意内容了.

python - re正则匹配模块

re模块 re 模块使 Python 语言拥有全部的正则表达式功能. compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象.该对象拥有一系列方法用于正则表达式匹配和替换. re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数. re.match函数 re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none. # (匹配规则,字符串,特殊标志) re.match(pattern

JS中正则匹配的三个方法match exec test的用法

javascript中正则匹配有3个方法,match,exec,test: match是字符串的一个方法,接收一个RegExp对象做为参数: match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配. 该方法类似 indexOf() 和 lastIndexOf(),但是它返回指定的值,而不是字符串的位置. exer 和test是RegExp对象的方法,接收一个字符串参数. 1. 如果你只是想判断字符串是否匹配某个正则表达式,就用test方法: 2.如果想一次性取出所有匹配到

42 python中正则中的分组 正则中匹配字符串的起始和结尾以及单词边界

第七课 正则中的分组 # 分组 # 正则表达式中用一对圆括号括起来的部分被称为一个分组 # '(\d\d\d)-(\d\d)' import re ''' 1. 只有圆括号括起来的部分才算一组,如果正则表达式中既有被圆括号括起来的部分, 也有未被圆括号括起来的部分,那么只将圆括号括起来的部分算一组 2. group方法,如果不指定参数,会返回匹配的整个字符串,如果加参数,会返回指定 分组的字符串,组索引从1开始 3. groups方法,以元组形式返回匹配的所有分组 4. 分组的索引是从1开始的

Python之正则re模块 --- findall()详解

1. findall() 函数的2种表示形式 1 import re 2 kk = re.compile(r'\d+') 3 kk.findall('one1two2three3four4') 4 #[1,2,3,4] 5 6 #注意此处findall()的用法,可传两个参数; 7 kk = re.compile(r'\d+') 8 re.findall(kk,"one123") 9 #[1,2,3] 2. 正则表达式可能遇到的坑  --- 正则表达式中的括号() 1. 当正则表达式中

grep中正则匹配的使用

如要匹配Computer或computer两个单词,可做如下操作: [Cc]mputer “.”允许匹配ASCII集中任意字符,或为字母,或为数字. 使用\{\}匹配模式结果出现的次数 匹配字母A出现两次,并以B结尾,操作如下: A\{2\}B 匹配A至少4次,使用: A\{4,\}B 如给出出现次数范围,例如A出现2次到4次之间: A\{2,4\}B 在grep命令中输入字符串参数时,最好将其用双引号括起来.例如:“mystring”.这样做 有两个原因,一是以防被误解为shell命令,二是可

python中,使用matplotlib绘图时,图片上文字无法显示问题。

在使用python过程中,我们往往需要使用matplotlib进行图片的绘制,在绘图过程中,我们有时需要在图片上进行文字的显示,在使用过程中,会出现文字无法显示的问题.如下图: 遇到上述问题我们只需在代码中加入如下语句即可解决: from pylab import mpl mpl.rcParams['font.sans-serif'] = ['SimHei']如下图: 原文地址:https://www.cnblogs.com/Leo-Xia/p/9997408.html