疯狂学习python中,最近又遇到不明白的地方啦----正则表达式的贪婪模式和非贪婪模式,又做了一些实践操作,如下:
.+?三个符号经常一起出现
首先来解释一下分别是什么意思:
“?”-----匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
"+"----匹配0个或多个的表达式
“.”----匹配任意字符,除了换行符
下面来看实践
# #------------------练习非贪婪/贪婪模式模式-----------
import re
str1 = 'telphone number is:123-456-789'
pattern1 = r'(.?)(\d+-\d+-\d+)'
pattern2 = r'(.+)(\d+-\d+-\d+)'
pattern3 = r'(.+?)(\d+-\d+-\d+)'
pattern4 = r'(.?+)(\d+-\d+-\d+)'#如果交换?与.就会直接报错
obj1 = re.match(pattern1,str1)
obj2 = re.match(pattern2,str1)
obj3 = re.match(pattern3,str1)
# obj4 = re.match(pattern4,str1)
print("-------?非贪婪--------\\n")
print(obj1)
# print(obj1.group())
# print(obj1.group(1))
# print(obj1.group(2))
print("-------*贪婪模式--------\\n")
print(obj2)
print(obj2.group(1))
print(obj2.group(2))
print("-------非贪婪模式-------\\n")
print(obj3)
print(obj3.group(1))
print(obj3.group(2))
# # print("-------测试*和?交换顺序会不会影响--这种不会输出none而是会直接报错\\n")
# print(obj4)
# # print(obj4.group(1))
# # print(obj4.group(2))
上述代码的运行结果是
对上面的代码进行简单的说明
1.为什么注释掉obj1的group()方法?
回答:可以看到并没有匹到字符,那么group是不能匹配到字符的,如果不注释掉就会报错
2.为什么定义了pattern4,却没有用呢,反而将其注释掉了呢?
回答:定义pattern3和pattern4的初衷是为了对比“+”“?”位置调换对匹配字符会不会有什么影响,可以看见pattern3是可以正常匹配的,但是pattern4不能正常工作,还会报错,打印对象不会出none,而是直接报下面这一堆错
整个就这样报错,我想我一定是踩雷了吧,我连搜为什么都不知道怎么搜,但是可以想见不可以像pattern4那样将“?”放在“+”前面
3.关于pattern2和pattern3是最重要的,简直是整篇笔记的点睛之笔
回答:这就是贪婪模式(pattern2)和非贪婪模式(pattern3)之间很明显的区别
注意看:pattern2的group(1)是telphone number is:12,所谓的贪婪模式就是按照正则一直匹配符合的字符直到遇到满足下一个条件的字符
(1)如果说两个用贪婪模式的正则,一前一后,遇见了两者都符合的字符,那么谁能匹配到这个字符呢?
这个就要依据当时有多少这样的字符啦,如果说有三个,那么占大头的一定是处于前面的字符
以这里说明,obj3中,数字123既符合前面的".“也符合后面的”\d",可以看见最后前面的字符直接争抢到了两个
(2)如果说,前面的正则是非贪婪,后面是贪婪,遇见了两者都符合的字符,那么谁能匹配到这个字符呢?
前面一定一个也抢不着,看采用用pattern3匹配的obj3,中123都被后面的"\d+"抢走了
(3)如果说,前面的正则是贪婪,后面是非贪婪,遇见了两者都符合的字符,那么谁能匹配到这个字符呢?
这里再做一个实践:
实践一:
import re
str1 = 'telphone number is:123-456-789'
pattern = r'(.+)(\d-\d+-\d+)'
pattern1 = r'(.+)(\d)'
pattern2 = r'(.+)(\d?)'
pattern3 = r'(.+)(\d-\d-\d)'
obj= re.match(pattern,str1)
print(obj)
print(obj.group(1))
print(obj.group(2))
输出的结果是:
这里说明一个问题,远水还是能救近火的,就是+在后面,还能能帮到前面的\d抢数字
实践二:
import re
str1 = 'telphone number is:123-456-789'
# pattern = r'(.+)(\d-\d+-\d+)'
# pattern1 = r'(.+)(\d)'
# pattern2 = r'(.+)(\d?)'
pattern3 = r'(.+)(\d-\d-\d)'
obj3= re.match(pattern3,str1)
print(obj3)
运行结果:
这是为什么呢,是因为没有了上面的+,后面的全部都被抢了到了第一个\d这里只剩下一个数字9,后面的正则都没有办法满足,然而整体又要都满足才能匹配成功,下面的实践三可以明确说明:
实践三:
import re
str1 = 'telphone number is:123-456-789'
# pattern = r'(.+)(\d-\d+-\d+)'
pattern1 = r'(.+)(\d)'
# pattern2 = r'(.+)(\d?)'
obj1= re.match(pattern1,str1)
print(obj1)
print(obj1.group(1))
print(obj1.group(2))
运行结果:
这个就不解释了,跟实践二结合起来就能理解
实践四:
import re
str1 = 'telphone number is:123-456-789'
# pattern = r'(.+)(\d-\d+-\d+)'
# pattern1 = r'(.+)(\d)'
pattern2 = r'(.+)(\d?)'
obj2= re.match(pattern2,str1)
print(obj2)
print(obj2.group(1))
print(obj2.group(2))
运行结果:
这个简直是对\d最狠的一种方式,如果你不要也行,那么我就全要了
就是这么贪!