1. 程式人生 > >正則表示式之貪婪匹配與非貪婪匹配

正則表示式之貪婪匹配與非貪婪匹配

. :匹配除 "\n" 之外的任何單個字元。要匹配包括 '\n' 在內的任何字元,請使用像 '[.\n]' 的模式

* :匹配0個或多個

使用 .* 的話就可以匹配任意長度的任意字元,但是有時候在使用 .*時就可能匹配不到物品們想要的結果,例:

import re

s='hello 1234567 world'
res = re.match('he.*(\d).*rld$',s)

print(res.group(1))

這裡要獲取中間的數字,正則表示式這樣寫看似沒什麼問題,但是執行結果卻只有 7 這是怎麼回事呢?

這裡就涉及一個貪婪匹配與非 貪婪匹配的問題了。在貪婪匹配下,.* 會匹配儘可能多的字元。正則表示式中.*後面是\d+,也就是至少一個數字,並沒有指定具體多少個數字,因此,.*就儘可能匹配多的字元,這裡就把123456匹配了,給\d+留下個可滿 足條件的數字 7.最後得到的內容就只有數字7了。            但這很明顯會給我們帶來很大的不便。有時候,匹配結果會莫名其妙少了部分內容。 其實,這裡只需要使用非貪婪匹配就好了。非貪婪匹配的寫法是.*?,多了一個?,那麼它可以達到怎樣的效果?我們再用例項看一下:

import re

s='hello 1234567 world'
res = re.match('he.*?(\d).*rld$',s)

print(res.group(1))

這裡我們只是將第一個.*改成了.*?. 轉變為非貪婪匹配。結果如下:            1234567            此時就可以成功獲取1234567了。原因可想而知,貪婪匹配是儘可能匹配多的字元,非貪婪匹配就是盡叮能匹配少的字元。當.*?匹配到hello後面的空白字元時,再往後的字元就是數字了,而\d+恰好可以匹配,那麼這裡. *?就不再進行匹配,交給\d+去匹配後面的數字。所以這樣,*?匹配了儘可能少的字元,\d+ 的結果就是1234567了。

            但是這裡需要注意,如果匹配的結果在字元結尾,.*?就有可能匹配不到任何結果了,因為他會盡可能匹配少的字元,例:

import re

s='hello 1234567 world/python'
res1 = re.match('he.*?(\d).*rld/(.*?)$',s)
res2 = re.match('he.*?(\d).*rld/(.*)$',s)

print('res1',res1.group(2))
print('res2',res2.group(2))

執行結果為:

res1

res2 python

可以觀察到,.*?沒有匹配到任何結果,而.*則儘可能匹配多的字元,成功得到了匹配結果。