爬蟲與Python:(三)基本庫的使用——4.re正則使用
正則表示式是一個特殊的字元序列,它能幫助使用者便捷地檢索一個字串是否與某種模式匹配。在爬蟲中我們經常會使用它來抓取到網頁原始碼或介面返回內容中匹配提取我們想要的資料。
Python自1.5增加了re模組,它提供Perl風格的正則表示式模式。re模組使Python語言擁有全部正則表示式的功能。
re模組也提供了與這些方法功能完全一致的函式,這些函式使用一個模式字串作為它們的第一個引數。本文主要介紹Python中常用的正則表示式處理函式。目錄如下:
1. re.match 函式
re.match嘗試從字串的起始位置匹配一個模式,如果不是起始位置匹配成功,那麼match()就返回None。re.match的語法格式如下:
re.match(pattern , string , flags=0)
引數說明如下表:
引數 | 描述 |
pattern | 匹配的正則表示式 |
string | 要匹配的字串 |
flags | 標誌位,用於控制正則表示式匹配方式,如是否區分大小寫、是否多行匹配等 |
匹配成功re.match返回一個匹配物件,否則返回None。還可以使用group(num)或groups匹配物件函式來獲取匹配表示式。
匹配物件方法 | 描述 |
group(num=0) | 匹配整個表示式的字串,group()可以一次輸入多個組號,在這種情況下它將返回一個包含那些組所對應的元組 |
group | 返回一個包含所有小組字串的元組,從1到所含的小組號 |
瞭解了以上內容,下面來一個示例程式碼:
1 import re 2 3 print(re.match('www','www.baidu.com').span()) # 在起始位置匹配 4 print(re.match('com','www.baidu.com')) # 不在起始位置匹配
執行後控制檯會輸出:
(0, 3)
None
獲取匹配表示式示例程式碼如下:
1 import re 2 3 line="Cats are smarter than dogs" 4 matchObj= re.match(r'(.*).are.(.*?).*',line); 5 6 if matchObj: 7 print("matachObj.group()",matchObj.group()) 8 print("matachObj.group(1)",matchObj.group(1)) 9 print("matachObj.group(2)",matchObj.group(2)) 10 else: 11 print("No match!")
執行後控制檯會輸出:
matachObj.group() Cats are smarter than dogs matachObj.group(1) Cats matachObj.group(2)
2. re.search 函式
re.search用於掃描整個字串並返回第一個成功的匹配。re.search的語法如下:
re.search(pattern , string ,flagx=0)
re.search有3個引數,作用與re.match一一致。需要注意的是flags引數可寫可不寫,因為它的底層給了預設值。
引數 | 描述 |
pattern | 匹配的正則表示式 |
string | 要匹配的字串 |
flags | 標誌位,用於控制正則表示式匹配方式,如是否區分大小寫、是否多行匹配等 |
示例程式碼如下:
1 import re 2 3 print(re.search('www','www.baidu.com').span()) # 在起始位置匹配 4 print(re.search('com','www.baidu.com').span()) # 不在起始位置匹配
執行後控制檯會輸出:
(0, 3)
(10, 13)
可以看到,匹配成功了,它會返回一個元組,該元組包含內容的開始位置和結束位置。
3. re.match 與re.search的區別
re.match只匹配字串的開始,如果字串開始不符合正則表示式,則匹配失敗,函式返回None;而re.search匹配整個字串,知道找到一個匹配。
示例程式碼如下:
1 import re 2 3 line="Cats are smarter than dogs" 4 5 6 # match匹配 7 matchObj= re.match(r'dogs',line); 8 if matchObj: 9 print("match-->matchObj.group()",matchObj.group()) 10 else: 11 print("No match!") 12 13 # search匹配 14 matchObj= re.search(r'dogs',line); 15 if matchObj: 16 print("search-->matchObj.group():",matchObj.group()) 17 else: 18 print("No match!")
執行後控制檯會輸出:
No match!
search-->matchObj.group(): dogs
4. 檢索和替換
當需要替換某段文字的某些內容時,例如:“等忙完這一陣,就可以接著忙下一陣了”。這裡想把“忙”字替換成“過”該如何解決?re中提供了模組re.sub可以用於替換字串中的匹配項。語法格式如下:
re.sub(pattern,repl,count=0 , flags=0)
re.sub的幾個引數說明如下:
引數 | 描述 |
pattern | 正則中的模式字串。 |
repl | 替換的字串,也可我一個函式。 |
string | 要被查詢或替換的原始字串 |
count | 模式匹配後替換的最大次數,預設wi0 ,表示替換所有的匹配 |
示例程式碼如下:
1 import re 2 3 st = "等忙完這一陣,就可以接著忙下一陣了。" 4 5 # 替換其中的“忙”字 6 new_str = re.sub(r'忙',"過",st) 7 print("替換後的句子:",new_str) # 替換後的句子: 等過完這一陣,就可以接著過下一陣了。
5. re.complile函式
re.complile用於編譯表示式,生成一個正則表示式{patter}物件,供match()和search()函式使用,re.complile函式語法格式如下:
re.compile(pattern,flags)
引數說明如下:
- patterern : 一個字串形式的正則表示式
- flags: 可選引數,表示匹配模式,如忽略大小寫、多行模式等。具體引數如下:
值 | 描述 |
rel | 忽略大小寫 |
re.I | 表示特殊字符集\w、\W、\b、\B、\s、\S 依賴當前環境 |
re.M | 多行模式 |
re.S | 即為 . ,並且包括換行符在內任意字元(.不包括換行符)。 |
re.U | 表示特殊字符集 |
re.X | 為了增加可讀性,忽略空格和#後面的註釋 |
下面我們來看一個示例:
1 import re 2 3 pattern = re.compile(r'\d+') # 用於匹配至少一個數字 4 m1 = pattern.match('one12wothree34hour') # 查詢頭部,沒有匹配 5 m2 = pattern.match('one12wothree34hour',2,10) # 從'e'的位置開始匹配,沒有匹配 6 m3 = pattern.match('one12wothree34hour',3,10) # 從1的位置開始匹配,正好匹配 7 8 print(m1) 9 print(m2) 10 print(m3) 11 print(m3.group(0)) 12 print(m3.start(0)) 13 print(m3.end(0)) 14 print(m3.span(0))
執行結果如下圖:
在來一個示例:
1 import re 2 3 pattern = re.compile(r'([a-z]+)([a-z]+)',re.I) # re.l表示忽略大小寫 4 m = pattern.match('Hello World Wide Web') 5 6 print(m) 7 print(m.group(0)) # 返回匹配成功的子串 8 print(m.span(0)) # 返回匹配成功的整個子串的索引 9 print(m.group(1)) # 返回第一個分組匹配成功的子串 10 print(m.span(1)) # 返回第一個分組匹配成功的子串的索引 11 print(m.group(2)) # 返回第二個分組匹配成功的子串 12 print(m.span(2)) # 返回第二個分組匹配成功的子串的索引 13 print(m.groups()) # 等價於(m.group(1),m.group(2),……) 14 print(m.group(3)) # 不存在第三個分組
執行結果如下圖:
6.findall 函式
finnal用於在字串中找到正則表示式所匹配的子串,並返回一個列表,如果沒有找到匹配的,則返回空列表。findall的語法如下:
findall(string,pos[,endpos])
引數說明如下:
- string : 待匹配的字串。
- pos 可選引數,指定字串的起始位置,預設為0。
- endpos : 可選引數,指定字串的結束位置,預設為字串長度
接下來,我們來查詢字串中的所有數字。
1 import re 2 3 pattern = re.compile(r'\d+') # 查詢數字 4 result1 = pattern.findall('runoob 123 google 456') 5 result2 = pattern.findall('run88oob123google456',0 ,10) 6 7 print(result1) 8 print(result2)
執行結果如下:
['123', '456'] ['88', '12']有志者,事竟成,破釜沉舟,百二秦關終屬楚; 苦心人,天不負,臥薪嚐膽,三千越甲可吞吳。