正則表達式的功能很多,除去之前介紹的驗證(字符串能否由正則表達式匹配),還可以從某個字符串中提取出某個字符串能匹配的所有文本。
上一章提到,re.search()如果匹配成功,返回一個MatchObject對象。這個對象包含了匹配的信息,比如表達式匹配的結果,可以像例2-7那樣,通過調用MatchObject.group(0)來獲得。這個方法以后詳細介紹,現在只需要了解一點:調用它可以得到表達式匹配的文本。
例2-7 通過MatchObject獲得匹配的文本
#注意這里使用鏈式編程 print re.search(r"\d{6}", "ab123456cd").group(0) 123456 print re.search(r"^<[^>]+>$", "<bold>").group(0) <bold>
這里再介紹一個方法:re.findall(pattern, string)。其中pattern是正則表達式,string是字符串。這個方法會返回一個數組,其中的元素是在string中依次尋找pattern能匹配的文本。
以郵政編碼的匹配為例,假設某個字符串中包含兩個郵政編碼:zipcode1:201203, zipcode2:100859,仍然使用之前匹配郵政編碼的正則表達式\d{6},調用re.findall()可以將這兩個郵政編碼提取出來,如例2-8。注意,這次要去掉表達式首尾的^和$,因為要使用正則表達式在字符串中尋找匹配,而不是驗證整個字符串能否由正則表達式匹配。
例2-8 使用re.findall()提取數據
print re.findall(r"\d{6}", "zipcode1:201203, zipcode2:100859") ['201203', '100859'] #也可以逐個輸出 for zipcode in re.findall(r"\d{6}", "zipcode1:201203, zipcode2:100859"): print zipcode
201203 100859
借助之前的匹配各種tag的正則表達式,還可以通過re.findall()將某個HTML頁面中所有的tag提取出來,下面以Yahoo首頁為例。
首先要讀入http://www.yahoo.com/的HTML源代碼,在Python中先獲得URL對應頁面的源代碼,保存到htmlSource變量中,然后針對匹配各類tag的正則表達式,分別調用re.findall(),獲得各類tag的列表(因為這個頁面中包含的tag太多,每類tag只顯示前3個)。
因為這段程序的輸出很多,在交互式界面下不方便操作和觀察,建議將這些代碼單獨保存為一個.py文件,比如findtags.py,然后輸入python findtags.py運行。如果輸入python沒有結果(一般在Windows下會出現這種情況),需要准確設定PATH變量,比如d:\Python\python。之后,就會看到例2-9顯示的結果。
例2-9 使用re.findall()提取tag
#導入需要的package import urllib import re #讀入HTML源代碼 sock = urllib.urlopen("http://yahoo.org/") htmlSource = sock.read() sock.close() #匹配,輸出結果([0:3]表示取前3個) print "open tags:" print re.findall(r"<[^/>][^>]*[^/>]>", htmlSource)[0:3] print "close tags:" print re.findall(r"</[^>]+>", htmlSource) [0:3] print "self-closing tags:" print re.findall(r"<[^>/]+/>", htmlSource) [0:3] open tags: ['<!DOCTYPE html>', '<html lang="en-US" class="y-fp-bg y-fp-pg-grad bkt701">', '<!-- m2 template 0 -->'] close tags: ['</title>', '</script>', '</script>'] self-closing tags: ['<br/>', '<br/>', '<br/>']