Python学习之路-----正则表达式(2)

匹配分组

| 匹配左右任意一个表达式
(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/
发布了76 篇原创文章 · 获赞 21 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/shen_chengfeng/article/details/103223781