python爬蟲 正規表示式詳解

ihav2carryon發表於2024-11-25

正規表示式

最近學校佈置了一個關於python爬蟲的期末作業,而我之前對python爬蟲一直都比較感興趣但是沒有系統的學過,就想借此機會開個新坑來系統學習和應用python爬蟲,那我們開始吧

正規表示式在爬蟲中扮演很重要的角色,幾乎所有有關字串的操作都可以使用正規表示式來完成,其可以幫助我們高效地從網頁獲取提取的資訊.在正式接觸爬蟲之前是非常有必要的學習正規表示式,所有關於正規表示式的操作都使用 python 標準庫中的 re 模組

元字元

元字元是正規表示式中具有特殊含義的字元,其用於構建更復雜的模式匹配規則

元字元 匹配內容 例項
. 匹配除換行符以外的任意單個字元 a.b 可以匹配 aXb, a1b, a b
\w 匹配所有普通字元(數字、字母或下劃線)→[a-z A-Z 0-9 _] \w{3}可以匹配abc,a1b,12_
\s 匹配任意的空白符,包括空格,製表符,換頁符等等 \s{3}可以匹配三個連續的空格
\d 匹配數字→[0-9] 如\d{3}可以匹配123,456 等等
\n 匹配一個換行符
\t 匹配一個製表符
\b 匹配一個單詞的結尾 \bcat\b匹配cat
^ 匹配字串的開始位置,多行模式下匹配每一行的開始 ^abc只能匹配abc開頭的字串
$ 匹配字串的結尾位置,多行模式下匹配每一行的結束 abc$只能匹配以abc結尾的字串
\W 匹配非字母或數字或下劃線→[^a-z A-Z 0-9 _] \W{3}可以匹配!!!,***等等
\D 匹配非數字→[^0-9] \D{3}可以匹配abc,xyz等等
\S 匹配非空白符 \S{3}可以匹配abc,123等等
或運算子,匹配左邊或右邊的表示式
( ) 正規表示式分組所用符號,匹配括號內的表示式,表示一個組。 (ab)+ 可以匹配ab,ab,abab等等
[...] 匹配字元組中的字元 [abc]可以匹配a,bc
[^...] (否定字符集) 匹配除了字元組中字元的所有字元 [^abc]可以匹配除a,b,c的所有字元
* 匹配前面的子表示式0次或多次 ab*c可以匹配ac,abc,abbc等等
+ 匹配前面的子表示式1次或多次 ab+c 可以匹配abc,abbc,但不能直接匹配ac
? 匹配前面的子表示式0次或1次 ab?c可以匹配ac,abc,不能匹配abbc
匹配前面的子表示式恰好 n 次 a{3}只能匹配aaa
匹配前面的子表示式至少 n 次 a{2,}可以匹配aa,aaa,aaaa等等
匹配前面的子表示式至少 n 次,最多 m 次 a{2,4}可以匹配aa,aaa,aaaa,但不能匹配aaaaa
\ 跳脫字元,用於匹配特殊字元 \.匹配字面上的.

貪婪模式與非貪婪模式

在正規表示式中,貪婪模式與非貪婪模式是兩種不同的匹配策略,都用於控制量詞(*,+,?,{})的行為

貪婪模式

  • 預設情況下,大多數的量詞都是貪婪的,貪婪模式會盡可能的多匹配字元,直到無法匹配

  • 常見的貪婪量詞:

    • *:匹配前面的子表示式零次或多次
    • +:匹配前面的子表示式一次或多次
    • ?:匹配前面的子表示式零次或一次
    • {n}:匹配前面的子表示式恰好 n 次
    • {n,}:匹配前面的子表示式至少 n 次
    • {n,m}:匹配前面的子表示式至少 n 次,最多 m 次
  • eg:假設一個字串”abcdadcde”,使用貪婪模式匹配a.*e

    import re
    
    text = "abcdadcde"
    pattern = re.compile(r'a.*e')
    
    match = pattern.search(text)
    print(match.group())  # 輸出abcdadcde
    
    • 在這個例子中,.* 會盡可能多地去匹配字元,直到最後一個e

非貪婪模式

  • 相比與貪婪模式,非貪婪模式會盡可能地少的去匹配字元,直到條件滿足為止,非貪婪模式透過在量詞後加上?來啟用
  • 常見的非貪婪量詞
    • *?:匹配前面的子表示式零次或多次,但儘可能少地匹配。
    • +?:匹配前面的子表示式一次或多次,但儘可能少地匹配。
    • ??:匹配前面的子表示式零次或一次,但儘可能少地匹配。
    • {n}?:匹配前面的子表示式恰好 n 次,但儘可能少地匹配。
    • {n,}?:匹配前面的子表示式至少 n 次,但儘可能少地匹配。
    • {n,m}?:匹配前面的子表示式至少 n 次,最多 m 次,但儘可能少地匹配

eg:假設先有一個字串”abcdeabcde”,其匹配模式修改為a.*?e

import re

text = "abcdeabcde"
pattern = re.compile(r'a.*?e')

match = pattern.search(text)
print(match.group())  # 輸出abcde

相關文章