匹配分组
| | 匹配左右任意一个表达式 |
(ab) | 将括号中字符作为一个分组 |
\num | 引用分组num匹配到的字符串 |
#匹配163邮箱
In [6]: result = re.match(r'\w{4,10}@163.com','[email protected]')
In [7]: print(result)
<re.Match object; span=(0, 12), match='[email protected]'>
#同时满足qq、163、126邮箱,在()中以|为分隔符分开各种邮箱
In [8]: result = re.match(r'\w{4,10}@(qq|163|126).com','[email protected]')
In [9]: print(result)
<re.Match object; span=(0, 12), match='[email protected]'>
In [10]: result = re.match(r'\w{4,10}@(qq|163|126).com','[email protected]')
In [11]: print(result)
<re.Match object; span=(0, 11), match='[email protected]'>
In [12]: result = re.match(r'\w{4,10}@(qq|163|126).com','[email protected]')
In [13]: print(result)
None
#匹配一个带区号的完整电话号码,-分开的部分都用()括起来,一个()就是一个分组
In [20]: result = re.match(r'(.{3})-(.{4})','010-6417')
In [21]: print(result)
<re.Match object; span=(0, 8), match='010-6417'>
#group()方法返回匹配到的完整字符串
In [22]: result.group()
Out[22]: '010-6417'
#groups()方法以元组的形式返回匹配到的所有分组
In [23]: result.groups()
Out[23]: ('010', '6417')
#group(index)返回某一个指定的分组
In [24]: result.group(1)
Out[24]: '010'
In [25]: result.group(2)
Out[25]: '6417'
#字符串s是被html和h1标签左右都包裹的字符串
In [32]: s = '<html><h1>hello world</h1></html>'
In [33]: s
Out[33]: '<html><h1>hello world</h1></html>'
#这是一个可以匹配到s这样格式的正则表达式
In [34]: result = re.match(r'<(.+)><(.+)>.*</.+></.+>',s)
In [35]: print(result)
<re.Match object; span=(0, 33), match='<html><h1>hello world</h1></html>'>
In [36]: result.group()
Out[36]: '<html><h1>hello world</h1></html>'
#但是会发现把s最右侧的html换成h1后依旧能匹配到
In [38]: result = re.match(r'<(.+)><(.+)>.*</.+></.+>','<html><h1>hello world</h1></h1>')
In [39]: result.group()
Out[39]: '<html><h1>hello world</h1></h1>'
#使用\num的正则表达式,把前两个标签中.+放到()中形成一个分组,因此左侧就有了两个分组,分别是1和2.又因为html标签都是成对出现的,因此右侧的分组使用前面的分组1和2
In [40]: result = re.match(r'<(.+)><(.+)>.*</\2></\1>','<html><h1>hello world</h1></h1>')
In [41]: print(result)
None
In [42]: result = re.match(r'<(.+)><(.+)>.*</\2></\1>','<html><h1>hello world</h1></html>')
In [43]: print(result)
<re.Match object; span=(0, 33), match='<html><h1>hello world</h1></html>'>
In [44]: result.group()
Out[44]: '<html><h1>hello wprld</h1></html>'
In [45]: result.groups()
Out[45]: ('html', 'h1')
In [46]: result = re.match(r'<(.+)><(.+)>(.*)</\2></\1>','<html><h1>hello world</h1></html>')
In [47]: result.groups()
Out[47]: ('html', 'h1', 'hello world')
search()方法
findall()方法
match()方法默认按正则表达式从待检测字符串中从左向右依次检查,如果第一个字符就不符合正则表达式的意思那么便直接返回None。
search()方法是按正则表达式从待检测字符串中从左向右依次检查,如果找到一个符合条件的子字符串就返回,不再进行后续的查找。
findall()方法是在seach()方法的基础上依旧继续查找,并将所有符合条件的子字符串放入列表中返回。
In [48]: result = re.match(r'\d+','hello123')
In [49]: print(result)
None
In [50]: result = re.search(r'\d+','hello123')
In [51]: print(result)
<re.Match object; span=(5, 8), match='123'>
In [52]: result.group()
Out[52]: '123'
In [53]: result = re.search(r'\d+','hello123world456')
In [54]: result.group()
Out[54]: '123'
In [55]: result = re.findall(r'\d+','hello123world456')
In [57]: print(result)
['123', '456']
sub()方法
在待检测字符串中寻找符合正则表达式的部分,然后替换成一个我们期待的子字符串。
re.sub(正则表达式,期待的结果,待检测字符串)
In [58]: result = re.sub(r'\d+','100','python=0')
In [59]: print(result)
python=100
还有一种使用方法是将函数名作为第二个参数传入,然后函数内部根据具体情况返回一个字符串,这个字符串最后也会替换到实际检测中的字符。这种方法更加灵活。
#定义一个函数,在这个函数中先打印了temp.group()的结果
In [64]: def add(temp):
...: strNum = temp.group()
...: print(strNum)
#注意得到的是字符串,因此做加减时要强制转化
...: num = int(strNum) + 1
...: return str(num)
...:
...:
In [65]: result = re.sub(r'\d+',add,'python=100,java=200')
100
200
#通过这个结果可以推测出实际上add方法被调用了两次
#实现了在原来值的基础上加1的结果
In [66]: print(result)
python=101,java=201
In [67]:
练习
得到链接的域名,如:http://www.badu.com/helloworld/?value1=1,得到http://www.baidu.com
关键就是:(1)关闭贪婪匹配做到准确分组(2)以分组形式传入
s = 'http://www.badu.com/helloworld/?value1=1'
In [91]: result = re.match(r'(http://.+?/)(.*)',s)
#关闭.+的贪婪匹配,使其准确分隔域名和后面的部分。
#加上(),以分组的形式返回
#以下的三个输入是为了方便看上一步的结果
In [92]: result.group()
Out[92]: 'http://www.badu.com/helloworld/?value1=1'
In [93]: result.group(1)
Out[93]: 'http://www.badu.com/'
In [94]: result.group(2)
Out[94]: 'helloworld/?value1=1'
#使用sub方法替换
#第二个参数直接使用匿名函数返回group(1)的结果
In [95]: result = re.sub(r'(http://.+?/)(.*)',lambda x:x.group(1),s)
In [96]: print(result)
http://www.badu.com/