1. 程式人生 > >《零基礎入門學習Python》第059講:論一隻爬蟲的自我修養7:正則表示式3

《零基礎入門學習Python》第059講:論一隻爬蟲的自我修養7:正則表示式3

今天我們先接著上節課的內容,把 Python3 正則表示式特殊符號及用法(詳細列表)這個表格講完:

上節課我們介紹了正則表示式的特殊字元中的 元字元,正則表示式的特殊字元除了 元字元之外呢,還有 一種就是通過反斜槓加上一個普通字元組成的特殊符號。我們接下來談談它們的含義。

\序號,這個我們上節課已經講過了,序號就是數字:

①引用序號對應的子組所匹配的字串,此時序號的範圍是 1~99,子組的序號是從 1 開始計算。

②如果序號是以 0 開頭,或者 3 位數字的長度。那麼不會被用於引用對應的子組,而是用於匹配八進位制數字所表示的ASCII 碼值對應的字元。

這在上節課已經講過了,我們接下來就講上節課沒有講過的:

\A :這個符號在預設情況下和 託字元(^)是一樣的,都是匹配輸入字串的開始位置。也就是說,要是前面是 \A 或者 ^ 符號,那麼這個字元就必須出現在字串的開頭,才能算是匹配。有不懂的,可以檢視上節課 託字元(^)的講解。

\Z:這個符號在預設情況下和 美元符號($)是一樣的,都表示匹配輸入字串的結束位置。

我們上面兩條都說的是 預設情況下,但不是說完全一樣的。因為正則表示式還有一個 編譯標誌的設定,如果說你設定了一個 re.MULTILINE 標誌,那麼託字元(^)也匹配換行符之後的位置,同時,美元符號($)也匹配換行符之前的位置。

但是呢,無論你設不設定這個標誌,這個 \A 和 \Z 都只能匹配字串的 開頭 和 結束 位置。

像這種匹配位置的字元,我們給它們一個名字,叫做 臨框斷言,言外之意就是它們不會匹配任何字元,它們只用於定位一個位置。

\b 也是一個臨框斷言,它是匹配一個單詞的邊界,單詞被定義為 Unidcode 的字母數字或下橫線字元。舉個例子:

>>> import re
>>> re.findall(r"\bFishC\b", "FishC.com!FishC_com!(FishC)")
['FishC', 'FishC']

上面只找到了兩個 FishC,你知道它哪一個FishC沒有找到嗎?(事實上是 FishC_com 中的FishC),因為下劃線也被認為是單詞字元,不是邊界。點號(.)感嘆號(!)、括號都被認為是單詞邊界。

接下來是 \B,其實就是與 \b 相反,匹配非單詞邊界。

舉個例子:py\B 會匹配字串 "python"、"py3"  或 "py2",但不會匹配 "py  "、"py." 或  "py!"

\d:① 對於 Unicode(str 型別)模式:匹配任何一個數字,包括 [0-9] 和其他數字字元;如果開啟了 re.ASCII 標誌,就只匹配 [0-9]。

② 對於 8 位(bytes 型別)模式:匹配 [0-9] 中任何一個數字。

\D:與 \d 相反,匹配任何非 Unicode 的數字;如果開啟了 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]

\w:① 對於 Unicode(str 型別)模式:匹配任何 Unicode 的單詞字元,基本上所有語言的字元都可以匹配當然也包括數字和下橫線;如果開啟了 re.ASCII 標誌,就只匹配 [a-zA-Z0-9_]

什麼是單詞字元?對於英文(就是ASCII)的話,像“Python”,P  y   t   h   o   n   這6個字元都是單詞字元,還有數字和下橫線也是。如果是 Unicode 的話, Unicode 是全球化的語言,像中文,中文什麼是單詞字元?例如“我愛Python”,其中的   我    愛   這兩個漢字也是單詞字元。

② 對於 8 位(bytes 型別)模式:匹配 ASCII 中定義的字母數字,即 [a-zA-Z0-9_]

舉個例子:

>>> re.findall(r"\w", "我愛Python3 (love_python.com!)")
['我', '愛', 'P', 'y', 't', 'h', 'o', 'n', '3', 'l', 'o', 'v', 'e', '_', 'p', 'y', 't', 'h', 'o', 'n', 'c', 'o', 'm']

除了 空格 括號 點號 感嘆號,其它的漢字、字母、下橫線、數字 都是單詞字元。

\W :其實就是與 \w 相反, 匹配任何非 Unicode 的單詞字元,;如果開啟了 re.ASCII 標誌,則相當於 [^a-zA-Z0-9_]

最後,正則表示式還支援大部分 Python 字串的轉義符號:\a,\b,\f,\n,\r,\t,\u,\U,\v,\x,\\

注1:\b 通常用於匹配一個單詞邊界,只有在字元類中才表示“退格”

注2:\u 和 \U 只有在 Unicode 模式下才會被識別

注3:八進位制轉義(\數字)是有限制的,如果第一個數字是 0,或者如果有 3 個八進位制數字,那麼就被認為是八進位制數;其他情況則被認為是子組引用;至於字串,八進位制轉義總是最多隻能是 3 個數字的長度。

 Python3 正則表示式特殊符號及用法(詳細列表)這個表格終於講解完畢了,還是那句話,別死記硬背,查用就行。

接下來講解下一個內容:編譯正則表示式:

什麼情況下需要編譯正則表示式?

如果你需要重複地使用某個正則表表達式,那麼你可以先把該正則表示式編譯成模式物件。

我們使用 re.compile() 方法來編譯……

re.compile 函式

compile 函式用於編譯正則表示式,生成一個正則表示式( Pattern )物件,供 match() 和 search() 這兩個函式使用。

語法格式為:

re.compile(pattern[, flags])

引數:

  • pattern : 一個字串形式的正則表示式
  • flags : 可選,表示匹配模式,比如忽略大小寫,多行模式等,具體引數為:
    1. re.I 忽略大小寫
    2. re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依賴於當前環境
    3. re.M 多行模式
    4. re.S 即為 . 並且包括換行符在內的任意字元(. 不包括換行符)
    5. re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依賴於 Unicode 字元屬性資料庫
    6. re.X 為了增加可讀性,忽略空格和 # 後面的註釋

      關於這6個編譯標誌的詳解可以檢視 Python3 如何優雅地使用正則表示式(詳解三)

>>> p = re.compile(r"[A-Z]")
>>> type(p)
<class '_sre.SRE_Pattern'>

我們把正則表示式 [A-Z] 進行編譯,賦值給 一個變數 p,這個變數 p 就是一個模式物件。

我們可以直接使用 p 進行 search() 方法 和 findall() 方法  的使用:

>>> p.search("I love Python")
<_sre.SRE_Match object; span=(0, 1), match='I'>
>>> p.findall("I love Python")
['I', 'P']

有些朋友可能會問,你是使用 模組級別的方法效率比較高,還是說使用編譯後的方法效率比較高,其實這個沒有一定的定論,因為兩種的優化差不多。這裡,如果你至少需要使用一次正則表示式,你直接使用 模組級別的方法就可以了,但是呢,如果你下面要多次使用 這個正則表示式,你就可以先對其進行編譯,再使用,這樣更方便。我們以方便為主,既然學習Python,就不要多考慮效率的問題了,能優化的,Python的設計者都已經優化得差不多了。

接下來我們來談談這個 編譯標誌

我們在 Python3 如何優雅地使用正則表示式(詳解三)裡有仔細的給大家列舉出來。

編譯標誌讓你可以修改正則表示式的工作方式。在 re 模組下,編譯標誌均有兩個名字:完整名和簡寫。

我們需要提一點的是 VERBOSE(簡寫 X)這個標誌,使用 re.VERBOSE(或者 re.X)在某些時候能給我們帶來很多好處。

因為呢,稍微一箇中等複雜度的正則表示式,你就會把它寫成人模狗樣,非常非常的複雜,為什麼呢?因為我們上節課已經說過了,正則表示式裡 你不能隨便加空格,因為空格它會被認為是其中的一個匹配元素,你不能加空格,不能加 Tab 鍵,不能 使用三重引號 換行,所以呢,你寫出來的東西就會看起來很難理解。但是如果你開啟了 VERBOSE,它就是支援 空格,支援Tab鍵,支援換行,也支援註釋的。