正規表示式
最近學校佈置了一個關於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,b 或c |
[^...] | (否定字符集) 匹配除了字元組中字元的所有字元 | 如[^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