python正則中的貪婪與非貪婪


當重復一個正則表達式時,如用 a*,操作結果是盡可能多地匹配模式。當你試着匹配一對對稱的定界符,如 HTML 標志中的尖括號。匹配單個 HTML 標志的模式不能正常工作,因為 .* 的本質是“貪婪”的

>>> s = '<html><head><title>Title</title>'
>>> len(s)
32
>>> print re.match('<.*>', s).span()
(0, 32)
>>> print re.match('<.*>', s).group()
<html><head><title>Title</title>
RE 在 "<html>" 中 匹配 "<",.* 會消耗掉字符串的剩余部分。RE 中保持更多的向左匹配, 不能在字符串結尾匹配“>”,因此正則表達式必須一個字符一個字符地回溯,直到它找到 > 的匹配。最終的匹配從 "<html" 中的 "<" 到 "</title>" 中的 ">",這變成了全文匹配,並不是你想要的結果。

在這種情況下,解決方案是使用不貪婪的限定符 *?、+?、?? 或 {m,n}?,盡可能匹配小的文本。在上面的例子里,在第一個 "<" 之后立即嘗試匹配 ">",當它失敗時,引擎一次增加一個字符,並在每步重試 匹配">"。這個處理將得到正確的結果:

>>> print re.match('<.*?>', s).group()
<html>

注意一下比較:

>>> re.findall(r"a(\d+?)""a23b")
        
['2']
>>> 
re.findall(r"a(\d+)""a23b")
        ['23']

---------------比較一下兩者的不同------------------------

>>> re.findall(r"a(\d+)b""a23b")
        
['23']
>>> 
re.findall(r"a(\d+?)b""a23b")

        
['23']

有時使用貪婪模式匹配網頁代碼時,會出現卡機情況,比如用這個語句:

sty_scr_tag = re.compile('(<style.*?[^>]*>.*?([\S\s]+)<\/style>)|(<script.*?[^>]*>.*?<\/script>)|(<script.*?[^>]*>.*?([\S\s]+?)<\/script>)',re.M)
content = sty_scr_tag.sub('', content)

去匹配baike.baidu.com這個網頁,你會發現編譯器一直卡在那里不會動,但當語句變成這個:

sty_scr_tag = re.compile('(<style.*?[^>]*>.*?<\/style>)|(<script.*?[^>]*>.*?<\/script>)|(<script.*?[^>]*>.*?([\S\s]+?)<\/script>)',re.M)
content = sty_scr_tag.sub('', content)

時,就可以了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM