开发者学堂课程【Python入门 2020年版:贪婪模式和非贪婪模式】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/639/detail/10451
贪婪模式和非贪婪模式
内容介绍:
一、演示
二、案例
三、练习
一、演示
在 Python 的正则表达式里,默认是贪婪模式,尽可能多的匹配
例如之前讲到的 m = re.search(r ‘m.*a’ , ‘o3rjomjadas’)按理以 m 开头 a 结尾可以匹配到 mja 或者 mjada,
但是
输入 print(m)
结果匹配到 mjada
这就是贪婪模式,会匹配到后面的 a
再来修改,增加一个?,
输入
m = re.search(r ‘m.*?a’ , ‘o3rjomjadas’)
再来输入 print(m)
结果显示匹配到的为 mja
若不加?,在 print 中增加.group(),在原始代码上输入
print(m.group())
结果显示为 mjada
在贪婪模式后面添加 ? ,可以将贪婪模式转换为非贪婪模式,
再例如输入
n = re.search(r ‘m.*?a’, ‘o3rjomjadas’)
print(n.group())
与
m = re.search(r ‘m.*a’ , ‘o3rjomjadas’)
print(m.group())做对比
显示结果为 mja,就是尽可能少的匹配。
另外,不仅可以限制贪婪模式和非贪婪模式,也可以限定次数出现一次或零次。
二、案例
输入
print(re.match(r“aa(\d+)”, “aa2343ddd”).group(1))
//第一组是\d+,第零组是 aa(\d+),第零组结果为 aa2343
试着打印结果,结果为2343,尽可能多取
输入
print(re.match(r“aa(\d+?)”, “aa2343ddd”).group(1))
打印结果为2,因为增加了一个?,就是尽可能少的获取,那若是改为第零组,按整体来取,结果是多少呢?
输入
print(re.match(r“aa(\d+?)”, “aa2343ddd”).group(0))
打印结果为 aa2
为了使看的更清晰,修改下代码格式,将上述两条代码改为
x1 = re.match(r “aa(\d+)”, “aa2343ddd”)
print(x1.group(0)) # aa2343
print(x1.group(1)) # 2343
x2 = re.match(r “aa(\d+?)”, “aa2343ddd”)
print(x2.group(0)) # aa2
print(x2.group(1)) #2
把?和+都去掉就是匹配单个,匹配单个就是 aa2,+是出现一次或多次。
若写为{2,},并且去掉?,这时匹配结果为多少?修改为
x2 = re.match(r “aa(\d{2, })”, “aa2343ddd”)
print(x2.group(0)) #aa2343
此处结果依然为 aa2343,因为写的是两次以上
print(x2.group(1)) #2343
但如果增加?,修改为
x2 = re.match(r “aa(\d{2, }?)”, “aa2343ddd”)
print(x2.group(0)) #aa23
结果就变为 aa23,而没有43,加?后尽可能少的匹配,匹配两个
print(x2.group(1)) #23
aa 之后\d 之后取两个以上,又增加了?,变为非贪婪模式,尽可能少取,两个以上就是取两个
再来看 x3,输入
x3 = re.match(r “aa(\d+)ddd”, “aa2343ddd”)
print(x3.group(0)) # aa2343ddd
第零组表示 aa(\d+)ddd,所以结果为全部
print(x3.group(1)) #2343
第一组就为2343
再来看 x4,输入
x4 = re.match(r “aa(\d+?)ddd”, “aa2343ddd”)
print(x4.group(0)) # aa2343ddd
第零组表示 aa(\d+?)ddd,?影响不了匹配的规则,在此处尽可能的少取并且又符合 aa\d+ddd 的规则,结果就为全部
print(x4.group(1)) #2343
第一组就为2343
再来看 x5,输入
x5 = re.match(r “aa(\d+?).*”, “aa2343ddd”)
print(x5.group(0)) # aa2343ddd
第零组依然能匹配到全部整体
print(x5.group(1)) #2
第一组是(\d+?),该结果为2,aa 匹配后,\d 尽可能少的匹配,就匹配一个,剩下的343ddd 为任意字符任意次,为.*
再来改变代码,增加一个?,并增加(),输入
x5 = re.match(r “aa(\d??)(.*)”, “aa2343ddd”)
print(x5.group(0))
print(x5.group(1))
print(x5.group(2))
则第零组代表 aa(\d??)(.*)全部
第一组代表(\d??)
第二组代表(.*)
显示结果分别为 aa2343ddd、空、2343ddd
前面的?表示次数限制,代表着出现0次或1次,即{,1},而又增加了一个?,将其变为非贪婪模式,尽可能少取,就取0,那么在 aa 匹配后(\d??)就不取任何值,为空,剩下的2343ddd 都给(.*)
另外,要想打印 aa,要将 aa 放在()中,为其增加一个分组,变为第一组即可打印
三、练习
现在有一个字符串,其中有一张图片的地址
src =‘<imgdataoringinal=“https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jp”
src= “https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg”
style= “display: inline;”>’
想要通过该字符串将图截下来
使用正则表达式
re.search(r‘https://.*\.jpg’, src)
从 https://开始寻找,.*找中间出现的任意字符,结尾是,jpg
输入 x6 = re.search(r ‘https://.*\.jpg’, src)
print(x6.group())
结果显示
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”
我们想要的结果只是前半段,但是后半段也有 jpg,所以也被取到
这时增加?,将贪婪模式变为非贪婪模式,尽可能少的取到 jpg
运行后结果就为
https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg
