python正則表達式簡介

之前未接觸過正則表達式,今日看python網絡爬蟲的源碼,裏面一行正則表達式匹配的代碼初看之下,不是很理解,代碼如下:
myItems = re.findall('<div.*?class="content".*?title="(.*?)">(.*?)</div>',unicodePage,re.S)

“.*?”這種匹配方式,按理解應該是匹配任意字符0個或多個(re.S模式,“.”可以匹配“\n”),但是這個“?”總覺的在這兒是多餘的,既然不理解,就敲代碼試試:
import re

patern = re.compile('www\..*')
match1 = patern.match("www.baidu.com")
if match1:
    print(match1.group())
else:
    print("match1 don't match")

#output
>>> ==================RESTART =============================
>>> 
www.baidu.com

這個結果,應該說是意料之中,加個“?”呢?
import re

patern = re.compile('www\..*?')
match1 = patern.match("www.baidu.com")
if match1:
    print(match1.group())
else:
    print("match1 don't match")

#output
>>> ==================RESTART =============================
>>> 
www.

竟然是這個結果。。。“.?”一個字符都沒匹配,按“.”、“”、“?”的匹配理解,也就是“*”“?”均匹配前面字符0次,纔會是這個結果,可是爲啥就是0次了? 
這就是正則表達式貪婪模式和非貪婪模式: 
貪婪模式,總是嘗試匹配儘可能多的字符; 
非貪婪模式則相反,總是嘗試匹配儘可能少的字符。 
Python裏數量詞默認是貪婪的,這就解釋了第一個匹配實驗,輸出結果爲”www.baidu.com”(貪婪模式),也就是說第二個匹配實驗是非貪婪模式,僅僅因爲加了“?”,繼續實驗
import re

patern = re.compile('www\..?')
match1 = patern.match("www.baidu.com")
if match1:
    print(match1.group())
else:
    print("match1 don't match")

#output
>>> ==================RESTART =============================
>>> 
www.b

此次匹配結果,顯然是貪婪模式。奇怪了,也就是“?”的特殊組合纔是非貪婪模式。 
網上搜索得如下說明: 
標準量詞修飾的子表達式,在可匹配可不匹配的情況下,總會先嚐試進行匹配,稱這種方式爲匹配優先,或者貪婪模式。此前介紹的一些量詞,“{m}”、“{m,n}”、“{m,}”、“?”、“*”和“+”都是匹配優先的。 
一些NFA正則引擎支持忽略優先量詞,也就是在標準量詞後加一個“?”,此時,在可匹配可不匹配的情況下,總會先忽略匹配,只有在由忽略優先量詞修飾的子表達式,必須進行匹配才能使整個表達式匹配成功時,纔會進行匹配,稱這種方式爲忽略優先,或者非貪婪模式。忽略優先量詞包括“{m}?”、“{m,n}?”、“{m,}?”、“??”、“*?”和“+?”。 

顯然“*?”的組合是非貪婪模式,猜想正確,原來如此啊。

還有就是, Python   中字符串前面加上 r 表示原生字符串,與大多數編程語言相同,正則表達式裏使用  "\"  作爲轉義字符,這就可能造成反斜槓困擾。假如你需要匹配文本中的字符  "\" ,那麼使用編程語言表示的正則表達式裏將需要4個反斜槓  "\\\\"  :前兩個和後兩個分別用於在編程語言裏轉義成反斜槓,轉換成兩個反斜槓後再在正則表達式裏轉義成一個反斜槓。Python裏的原生字符串很好地解決了這個問題,這個例子中的正則表達式可以使用  r"\\"  表示。同樣,匹配一個數字的  "\\d"  可以寫成  r"\d"  。有了原生字符串,你再也不用擔心是不是漏寫了反斜槓,寫出來的表達式也更直觀。
\b   匹配一個單詞邊界,也就是指單詞和空格間的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。   \B   匹配非單詞邊界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。
match()   函數只檢測RE是不是在string的開始位置匹配, search() 會掃描整個 string 查找匹配, 也就是說  match()  只有在0位置匹配成功的話纔有返回,如果不是開始位置匹配成功的話, match()  就返回  none


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章