正则表达式匹配分组等其他的情况
字符 | 功能 |
---|---|
| | 匹配左右任意一个表达式 |
(ab) | 将括号中字符作为一个分组,可以和|一起使用(ab|cd)表示匹配括号内分组中的一个 |
\num | 引用分组num匹配到的字符串 |
(?P<name>) | 分组起别名 |
(?P=name) | 引用别名为name分组匹配到的字符串 |
案例演示1:
import re
pattern = '^M?M?M?(CM|CD|D?C?C?C?)$'
str = 'MMDCC'
s= re.search(pattern,str)
print(s.group()) #MMDCC,将()做一个分组,然后|表示匹配其左右任意一个表达式
str1 ='MCMCD'
s1 = re.search(pattern,str1)
print(s1.group()) #匹配失败,因为CM和DC在|的左右,只可以匹配其中之一
案例演示2:
import re
pattern ='^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$'
s1 = re.search(pattern, 'MDLV')
print(s1.group()) #MDLV.第一个M匹配,第一个括号匹配D.第二个括号L.第三个括号V.
s2 = re.search(pattern,'')
print(s2.group()) #匹配成功空串.第一个M可以为空,第一个括号DC可以为空,后面同理
s3 = re.search(pattern, 'MMDCLXVI')
print(s3.group()) #MMDCLXVI
s4 = re.search(pattern, 'MMMDCCCLXXXVIII')
print(s4.group()) #MMMDCCCLXXXVIII
s5 = re.search(pattern,'I')
print(s5.group()) #I 前面为空,最后一个括号匹配I
案例3:group的使用补充
import re
'''
group()将匹配的结果直接以字符串的形式返回
groups()将正则匹配中的分组()匹配结果以元组形式返回
group(1) 将groups分组匹配的结果分别取出,就是第一个()的内容,同理group(2)就是第二个()内容
'''
phonePattern = re.compile(r'^\D*(\d{3})\D*(\d{3})\D*(\d{4})\D*(\d*)$')
s1 = phonePattern.search('(800)5551212 ext.1234')
#注意下面group(),groups(),group(1)的结果
print(s1.group()) #(800)5551212 ext.1234
print(s1.groups()) #('800', '555', '1212', '1234')
print(s1.group(1)) #800
案例4:\num分组匹配的使用,好多人没搞明白
import re
#目标中列表里匹配出<html><h1>www.bai.com</h1></html>
labels = ["<html><h1>www.bai.com</h1></html>", "<html><h1>www.sina.cn</h2></html>"]
for label in labels:
ret = re.match(r"<(\w*)><(\w*)>.*</\2></\1>", label)
#这里所谓的\2指的是第二个分组匹配的结果,因为一个()表示一个分组,也就是正则里的第二个括号
# 所以\2代表的分组就是第二个(\w*)匹配的结果,这里也就是h1.
# ret1 = re.match(r"<(\w*)><(\d*)>.*</\2></\1>", label)
#注意如果这里讲第二个()换成(\d*),就会匹配失败
if ret:
print("%s 是符合要求的标签" % ret.group())
else:
print("%s 不符合要求" % label)
'''
<html><h1>www.bai.com</h1></html> 是符合要求的标签
<html><h1>www.sina.cn</h2></html> 不符合要求
'''
总结:
^ 匹配字符串开始位置。
• $ 匹配字符串结束位置。
• \b 匹配一个单词边界。
• \d 匹配一个数字。
• \D 匹配一个任意的非数字字符。
• x? 匹配可选的 x 字符。换句话说,就是 0 个或者 1 个 x 字符。
• x* 匹配 0 个或更多的 x。
• x+ 匹配 1 个或者更多 x。
• x{n,m} 匹配 n 到 m 个 x,至少 n 个,不能超过 m 个。
• (a|b|c) 匹配单独的任意一个 a 或者 b 或者 c。
• (x) 这是一个组,它会记忆它匹配到的字符串。你可以用
re.search 返回的匹配对象的 groups()函数来获取到匹配的值
python正则匹配的贪婪和非贪婪
Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;
非贪婪则相反,总是尝试匹配尽可能少的字符。
在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪。
>>> s="This is a number 234-235-22-423"
>>> r=re.match(".+(\d+-\d+-\d+-\d+)",s)
>>> r.group(1)
'4-235-22-423'
>>> r=re.match(".+?(\d+-\d+-\d+-\d+)",s)
>>> r.group(1)
'234-235-22-423'
>>>
正则表达式模式中使用到通配字,那它在从左到右的顺序求值时,会尽量“抓取”满足匹配最长字符串,在我们上面的例子里面,“.+”会从字符串的启始处抓取满足模式的最长字符,其中包括我们想得到的第一个整型字段的中的大部分,“\d+”只需一位字符就可以匹配,所以它匹配了数字“4”,而“.+”则匹配了从字符串起始到这个第一位数字4之前的所有字符。
解决方式:非贪婪操作符“?”,这个操作符可以用在"*","+","?"的后面,要求正则匹配的越少越好。
>>> re.match(r"aa(\d+)","aa2343ddd").group(1)
'2343'
>>> re.match(r"aa(\d+?)","aa2343ddd").group(1)
'2'
>>> re.match(r"aa(\d+)ddd","aa2343ddd").group(1)
'2343'
>>> re.match(r"aa(\d+?)ddd","aa2343ddd").group(1)
'2343'
>>>
统一声明:关于原创博客内容,可能会有部分内容参考自互联网,如有原创链接会声明引用;如找不到原创链接,在此声明如有侵权请联系删除哈。关于转载博客,如有原创链接会声明;如找不到原创链接,在此声明如有侵权请联系删除哈。