WELCOME

不积跬步,无以至千里;不积小流,无以成江海。

Python正则表达式--分组和re.Match类方法和贪婪

1.正则表达式的分组

  分组就是用一对圆括号“()”括起来的正则表达式,匹配出的内容就表示一个分组。从正则表达式的左边开始看,看到的第一个

左括号“(”表示第一个分组,
第二个表示第二个分组,依次类推,需要注意的是,有一个隐含的全局分组(就是0),就是整个正则

表达式。
分完组以后,要想获得某个分组的内容,直接使用group(num)和groups()函数去直接提取就行。

在括号中还可以结合 | 使用
1 # 匹配区号
2 phone = '0713-2875338'
3 result = re.match(r'(\d{3}|\d{4})-(\d{7})$', phone)
4 print(result)  # >> <re.Match object; span=(0, 12), match='0713-2875338'>
5 print(result.group(1))  # >> 0713
6 print(result.group(2))  # >> 2875338
1 result = re.match(r'<([0-9a-zA-Z]+)>(.+)</\1>$', msg1)  # \1表示和第一组的一样
2 print(result)  # >> <re.Match object; span=(0, 14), match='<h1>hello</h1>'>
3 print(result.group(1))  # >> h1
4 print(result.group(2))  # >> hello
1 msg = '<html><h1>hello</h1></html>'
2 result = re.match(r'<([0-9a-zA-Z]+)><([0-9a-zA-Z]+)>(.+)</\2></\1>$', msg) # \2表示和第二组<([0-9a-zA-Z]+)>匹配一样,\1表示和第一组<([0-9a-zA-Z]+)>匹配一样
3 print(result)  # >> <re.Match object; span=(0, 27), match='<html><h1>hello</h1></html>'>
4 print(result.group(1))  # >> html
5 print(result.group(2))  # >> h1
6 print(result.group(3))  # >> hello

上面所用到的\1和\21...用起来很混乱,所以怎么解决呢?
可以用(?P<命名>) 后面引用(?P=命名)

1 msg = '<html><h1>hello</h1></html>'
2 result = re.match(r'<(?P<name1>[0-9a-zA-Z]+)><(?P<name2>[0-9a-zA-Z]+)>(.+)</(?P=name2)></(?P=name1)>', msg)
3 print(result)  # >> <re.Match object; span=(0, 27), match='<html><h1>hello</h1></html>'>
4 print(result.group(1))  # >> html
5 print(result.group(2))  # >> h1
6 print(result.group(3))  # >> hello

 

2.re.Match类介绍

  当我们调用re.match方法、re.search方法,或者对re.finditer方法的结果进行迭代时,拿到的数据类型都是

re.Match对象(re.findall返回的是列表,元素是str类型,故不是re.Match对象)

 

 1 import re
 2 
 3 x = re.match(r'h', 'hello')
 4 y = re.search(r'e', 'hello')
 5 z = re.finditer(r'l', 'hello')
 6 w = re.findall(r'l', 'hello')
 7 print(type(x))  # >> <class 're.Match'>
 8 print(type(y))  # >> <class 're.Match'>
 9 for a in z:
10     print(type(a))  # <class 're.Match'>
11 print(type(w))  # >> <class 'list'>
12 print(type(w[1]))  # >> <class 'str'>

 

这个类里定义了相关的属性,可以直接让我们来使用。

属性和方法    说 明
pos      搜索的开始位置
endpo    搜索的结束位置
strin    搜索的字符串
re          当前使用的正则表达式的对象
lastindex      最后匹配的组索引
lastgroup      最后匹配的组名
group(index=0)    某个分组的匹配结果。如果index等于0,便是匹配整个正则表达式
groups()       所有分组的匹配结果,每个分组的结果组成一个列表返回
groupdict()     返回组名作为key,每个分组的匹配结果座位value的字典
start([group])    获取组的开始位置
end([group])     获取组的结束位置
span([group])    获取组的开始和结束位置
expand(template)    使用组的匹配结果来替换模板template中的内容,并把替换后的字符串返回

 

1 import re
2 
3 ret = re.search(r'(abc)+', 'xxxabcabcbcdef')
4 print(ret.pos)  # 搜索开始的位置,默认是0
5 print(ret.endpos)  # 搜索结束的位置,默认是字符串的长度 15
6 print(ret.group(0))  # abcabcabc 匹配整个表达式
7 print(ret.group(1))  # abc 第一次匹配到的结果
8 print(ret.span())  # (3, 9) 开始和结束位置
9 print(ret.groups())  # 表示当正则表达式里有多个分组时,多个分组的匹配结果

 

 

3.贪婪与非贪婪

Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;

非贪婪则相反,总是尝试匹配尽可能少的字符。

在*,?,+,{m,n}后面加上 ?使贪婪变成非贪婪。

 

 1 import re
 2 
 3 # python里数量词默认是贪婪的,总是尝试匹配尽可能多的
 4 # 如果想将贪婪模式变成非贪婪模式
 5 msg = 'abc123ba'
 6 result = re.match(r'abc(\d+)', msg)
 7 result1 = re.match(r'abc(\d+?)', msg)
 8 print(result)
 9 print(result1)
10 
11 '''
12 <re.Match object; span=(0, 6), match='abc123'>
13 <re.Match object; span=(0, 4), match='abc1'>
14 '''

 

1 path = '<img data-original="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" src="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" style="display: inline;">'
2 
3 result = re.search(r'https://.*?.jpg', path)
4 
5 print(result.group())
6 '''
7 https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg
8 '''

 

posted @ 2022-04-04 22:20  Ambitious~  阅读(346)  评论(0)    收藏  举报