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 '''
作者:Ambitious
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!