洗禮靈魂,修煉python(63)--爬蟲篇—re模塊/正則表達式(1)


爬蟲篇前面的某一章了,我們要爬取網站頁面源代碼的數據,要從中獲取到我們想要的數據,是不是感覺很費力,確實費力對吧?那么有沒有什么有利的工具來解決這個問題呢?那就是這一篇博文的主題——

正則表達式簡介

1.概念理解

正則表達式(Regular expressions 也稱為 REs,或 regexes 或 regex patterns)本質上是一個微小的且高度專業化的編程語言。正則表達式是一個特殊的字符序列,它能幫助你方便的檢查一個字符串是否與某種模式匹配。使用正則表達式,你需要指定一些規則來描述那些你希望匹配的字符串集合。這些字符串集合可能包含英語句子,e-mail 地址,任何你想要的東東。正則表達式模式被編譯成一系列的字節碼,然后由一個 C 語言寫的匹配引擎所執行(正因為正則表達式引擎是用 C 語言寫的,所以效率是極高)。對於高級的使用,你可能需要更關注匹配引擎是如何執行給定的 re,並通過一定的方式來編寫 re,以便產生一個可以運行得更快的字節碼。利用正則表達式,可以處理你 98% 的文本任務。
正則表達式對於Python來說並不是獨有的。它被嵌入到 Python 中,並通過 re 模塊提供給程序猿使用

提到正則表達式,那么必須得提到正則表達式的“幾元大將”,它們有一個統一的名字——元家軍,又名元字符

 

2.元字符

.   ^   $   *   +   ?   { }   [ ]   \   |   ( )

如果沒有這幾個“將士”,那么正則表達式將變得和字符串的find()方法無二了。

 

那么這幾個“將士”什么來路呢?分別又有什么特技呢?

 

:匹配任意字符,除了換行符。而當re.DOTALL標記被指定時,則可以匹配包括換行符的任意字符

^  :匹配字符串的開頭,脫字符

  • 匹配輸入字符串的開始位置
  • 如果設置了 re.MULTILINE 標志,^ 也匹配換行符之后的位置

:匹配字符串的末尾,如果設置了 re.MULTILINE 標志,$ 也匹配換行符之前的位置

  :匹配前面的子表達式零次或多次,等價於 {0,}
:匹配前面的子表達式一次或多次,等價於 {1,}
:匹配前面的子表達式零次或一次,等價於 {0,1}

{M,N} :M 和 N 均為非負整數,其中 M <= N,表示前邊的 RE 匹配 M ~ N 次

  • {M,} 表示至少匹配 M 次
  • {,N} 等價於 {0,N}
  • {N} 表示需要匹配 N 次

[...]  :字符類,匹配所包含的任意一個字符

  • 連字符 - 如果出現在字符串中間表示字符范圍描述;如果如果出現在首位則僅作為普通字符
  • 特殊字符僅有反斜線 \ 保持特殊含義,用於轉義字符。其它特殊字符如 *、+、? 等均作為普通字符匹配
  • 脫字符 ^ 如果出現在首位則表示匹配不包含其中的任意字符;如果 ^ 出現在字符串中間就僅作為普通字符匹配

  :(下面還有詳解)

  •  將一個普通字符變成特殊字符,例如 \d 表示匹配所有十進制數字
  • 解除元字符的特殊功能,例如 \. 表示匹配點號本身
  • 引用序號對應的子組所匹配的字符串

| :A | B,表示匹配正則表達式 A 或者 B

 

(...)  :匹配圓括號中的正則表達式,或者指定一個子組的開始和結束位置。子組的內容可以在匹配之后被 \數字 再次引用

 

3.還有一些擴展出來的功能:

*?, +?, ??
默認情況下 *、+ 和 ? 的匹配模式是貪婪模式(即會盡可能多地匹配符合規則的字符串);*?、+? 和 ?? 表示啟用對應的非貪婪模式。

(?...):(? 開頭的表示為正則表達式的擴展語法(下邊這些是 Python 支持的所有擴展語法)

(?aiLmsux):
  • (? 后可以緊跟着 'a','i','L','m','s','u','x' 中的一個或多個字符,只能在正則表達式的開頭使用
  •  每一個字符對應一種匹配標志:re-A(只匹配 ASCII 字符),re-I(忽略大小寫),re-L(區域設置),re-M(多行模式), re-S(. 匹配任何符號),re-X(詳細表達式),包含這些字符將會影響整個正則表達式的規則
  • 當你不想通過 re.compile() 設置正則表達式標志,這種方法就非常有用啦。注意,由於 (?x) 決定正則表達式如何被解析,所以它應該總是被放在最前邊(最多允許前邊有空白符)。如果 (?x) 的前邊是非空白字符,那么 (?x) 就發揮不了作用了。

(?:...):非捕獲組,即該子組匹配的字符串無法從后邊獲取

(?P<name>...):命名組,通過組的名字(name)即可訪問到子組匹配的字符串
(?P=name):反向引用一個命名組,它匹配指定命名組匹配的任何內容
(?#...):注釋,括號中的內容將被忽略
(?=...):前向肯定斷言。如果當前包含的正則表達式(這里以 ... 表示)在當前位置成功匹配,則代表成功,否則失敗。一旦該部分正則表達式被匹配引擎嘗試過,就不會繼續進行匹配了;剩下的模式在此斷言開始的地方繼續嘗試。

(?!...):前向否定斷言。這跟前向肯定斷言相反(不匹配則表示成功,匹配表示失敗)。

(?<=...):后向肯定斷言。跟前向肯定斷言一樣,只是方向相反。

(?<!...):后向否定斷言。跟前向肯定斷言一樣,只是方向相反。

(?(id/name)yes-pattern|no-pattern):如果子組的序號或名字存在的話,則嘗試 yes-pattern 匹配模式;否則嘗試 no-pattern 匹配模式,no-pattern 是可選的
比如(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$) 是一個匹配郵件格式的正則表達式,可以匹配 <user@fishc.com> 和 'user@fishc.com',但是不會匹配 '<user@fishc.com' 或 'user@fishc.com>'
 

\
 
 
當\作轉義符號時:

正則表達式還支持大部分 Python 字符串的轉義符號:\a,\b,\f,\n,\r,\t,\u,\U,\v,\x,\\
  • \b 通常用於匹配一個單詞邊界,只有在字符類中才表示“退格”
  • \u 和 \U 只有在 Unicode 模式下才會被識別
  • 八進制轉義(\數字)是有限制的,如果第一個數字是 0,或者如果有 3 個八進制數字,那么就被認為是八進制數;其他情況則被認為是子組引用;至於字符串,八進制轉義總是最多只能是 3 個數字的長度


\序號:
  • 引用序號對應的子組所匹配的字符串,子組的序號從 1 開始計算
  • 如果序號是以 0 開頭,或者 3 個數字的長度。那么不會被用於引用對應的子組,而是用於匹配八進制數字所表示的 ASCII 碼值對應的字符

\A:匹配輸入字符串的開始位置
\Z:匹配輸入字符串的結束位置
\b:匹配一個單詞邊界,單詞被定義為 Unidcode 的字母數字或下橫線字符

\B:匹配非單詞邊界,其實就是與 \b 相反

\d:
  • 對於 Unicode(str 類型)模式:匹配任何一個數字,包括 [0-9] 和其他數字字符;如果開啟了 re.ASCII 標志,就只匹配 [0-9]
  • 對於 8 位(bytes 類型)模式:匹配 [0-9] 中任何一個數字
\D:匹配任何非 Unicode 的數字,其實就是與 \d 相反;如果開啟了 re.ASCII 標志,則相當於匹配 [^0-9]
\s:
  • 對於 Unicode(str 類型)模式:匹配 Unicode 中的空白字符(包括 [ \t\n\r\f\v] 以及其他空白字符);如果開啟了 re.ASCII 標志,就只匹配 [ \t\n\r\f\v]
  • 對於 8 位(bytes 類型)模式:匹配 ASCII 中定義的空白字符,即 [ \t\n\r\f\v]
\S:匹配任何非 Unicode 中的空白字符,其實就是與 \s 相反;如果開啟了 re.ASCII 標志,則相當於匹配 [^ \t\n\r\f\v]
\w:
  • 對於 Unicode(str 類型)模式:匹配任何 Unicode 的單詞字符,基本上所有語言的字符都可以匹配,當然也包括數字和下橫線;如果開啟了 re.ASCII 標志,就只匹配 [a-zA-Z0-9_]
  • 對於 8 位(bytes 類型)模式:匹配 ASCII 中定義的字母數字,即 [a-zA-Z0-9_]
\W:匹配任何非 Unicode 的單詞字符,其實就是與 \w 相反;如果開啟了 re.ASCII 標志,則相當於 [^a-zA-Z0-9_]
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM