Python正規表示式


正規表示式是一個特殊的字元序列,可以幫助您使用模式中保留的專門語法來匹配或查詢其他字串或字串集。 正規表示式在UNIX世界中被廣泛使用。

註:很多開發人員覺得正規表示式比較難以理解,主要原因是缺少使用或不願意在這上面花時間。

re模組在Python中提供對Perl類正規表示式的完全支援。如果在編譯或使用正規表示式時發生錯誤,則re模組會引發異常re.error

在這篇文章中,將介紹兩個重要的功能,用來處理正規表示式。 然而,首先是一件小事:有各種各樣的字元,這些字元在正規表示式中使用時會有特殊的意義。 為了在處理正規表示式時避免混淆,我們將使用:r'expression'原始字串。

匹配單個字元的基本模式

編號 表示式 描述
1 a, X, 9, < 普通字元完全匹配。
2 . 匹配任何單個字元,除了換行符’\n
3 \w 匹配「單詞」字元:字母或數位或下劃線[a-zA-Z0-9_]
4 \W 匹配任何非字詞。
5 \b 字詞與非字詞之間的界限
6 \s 匹配單個空格字元 - 空格,換行符,返回,製表符
7 \S 匹配任何非空格字元。
8 \t, \n, \r 製表符,換行符,退格符
9 \d 十進位制數[0-9]
10 ^ 匹配字串的開頭
11 $ 匹配字串的末尾
12 \ 抑制字元的「特殊性」,也叫跳脫字元。

編譯標誌

編譯標誌可以修改正規表示式的某些方面。標誌在re模組中有兩個名稱:一個很長的名稱,如IGNORECASE,和一個簡短的單字母形式,如I

編號 標誌 含義
1 ASCII, A \w\b\s\d之間的幾個跳脫只匹配ASCII字元與相應的屬性。
2 DOTALL, S 匹配任何字元,包括換行符
3 IGNORECASE, I 不區分大小寫匹配
4 LOCALE, L 做一個區域感知的匹配
5 MULTILINE, M 多行匹配,影響^$
6 VERBOSE, X (for ‘extended’) 啟用詳細的RE,可以更乾淨,更容易理解

1.match函式

此函式嘗試將RE模式與可選標誌的字串進行匹配。

下面是函式的語法 -

re.match(pattern, string, flags = 0)

這裡是引數的描述 -

  • pattern - 這是要匹配的正規表示式。
  • string - 這是字串,它將被搜尋用於匹配字串開頭的模式。 |
  • flags - 可以使用按位元OR(|)指定不同的標誌。 這些是修飾符,如下表所列。

re.match函式在成功時返回匹配物件,失敗時返回None。使用match(num)groups()函式匹配物件來獲取匹配的表示式。

編號 匹配物件 描述
1 group(num = 0) 此方法返回整個匹配(或特定子組num)
2 groups() 此方法返回一個元組中的所有匹配子組(如果沒有,則返回為None)

範例

#!/usr/bin/python3
import re

line = "Cats are smarter than dogs"

matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)

if matchObj:
   print ("matchObj.group() : ", matchObj.group())
   print ("matchObj.group(1) : ", matchObj.group(1))
   print ("matchObj.group(2) : ", matchObj.group(2))
else:
   print ("No match!!")

當執行上述程式碼時,會產生以下結果 -

matchObj.group() :  Cats are smarter than dogs
matchObj.group(1) :  Cats
matchObj.group(2) :  smarter

2.search函式

此函式嘗試將RE模式與可選標誌的字串進行匹配。

下面是這個函式的語法 -

re.match(pattern, string, flags = 0)

這裡是引數的描述 -

  • pattern - 這是要匹配的正規表示式。
  • string - 這是字串,它將被搜尋用於匹配字串開頭的模式。 |
  • flags - 可以使用按位元OR(|)指定不同的標誌。 這些是修飾符,如下表所列。

re.search函式在成功時返回匹配物件,否則返回None。使用match物件的group(num)groups()函式來獲取匹配的表示式。

編號 匹配物件 描述
1 group(num = 0) 此方法返回整個匹配(或特定子組num)
2 groups() 此方法返回一個元組中的所有匹配子組(如果沒有,則返回為None)

範例

#!/usr/bin/python3
import re

line = "Cats are smarter than dogs";

searchObj = re.search( r'(.*) are (.*?) .*', line, re.M|re.I)

if searchObj:
   print ("searchObj.group() : ", searchObj.group())
   print ("searchObj.group(1) : ", searchObj.group(1))
   print ("searchObj.group(2) : ", searchObj.group(2))
else:
   print ("Nothing found!!")

當執行上述程式碼時,會產生以下結果 -

matchObj.group() :  Cats are smarter than dogs
matchObj.group(1) :  Cats
matchObj.group(2) :  smarter

3.匹配與搜尋

Python提供基於正規表示式的兩種不同的原始操作:match檢查僅匹配字串的開頭,而search檢查字串中任何位置的匹配(這是Perl預設情況下的匹配)。

範例

#!/usr/bin/python3
import re

line = "Cats are smarter than dogs";

matchObj = re.match( r'dogs', line, re.M|re.I)
if matchObj:
   print ("match --> matchObj.group() : ", matchObj.group())
else:
   print ("No match!!")

searchObj = re.search( r'dogs', line, re.M|re.I)
if searchObj:
   print ("search --> searchObj.group() : ", searchObj.group())
else:
   print ("Nothing found!!")

當執行上述程式碼時,會產生以下結果 -

No match!!
search --> matchObj.group() :  dogs

4.搜尋和替換

使用正規表示式re模組中的最重要的之一是sub

模組

re.sub(pattern, repl, string, max=0)

此方法使用repl替換所有出現在RE模式的字串,替換所有出現,除非提供max。此方法返回修改的字串。

範例

#!/usr/bin/python3
import re

phone = "2018-959-559 # This is Phone Number"

# Delete Python-style comments
num = re.sub(r'#.*$', "", phone)
print ("Phone Num : ", num)

# Remove anything other than digits
num = re.sub(r'\D', "", phone)    
print ("Phone Num : ", num)

當執行上述程式碼時,會產生以下結果 -

Phone Num :  2018-959-559
Phone Num :  2018959559

5.正規表示式修飾符:選項標誌

正規表示式文字可能包含一個可選修飾符,用於控制匹配的各個方面。 修飾符被指定為可選標誌。可以使用互斥或(|)提供多個修飾符,如前所示,可以由以下之一表示 -

編號 修辭符 描述
1 re.I 執行不區分大小寫的匹配。
2 re.L 根據當前語言環境解釋單詞。這種解釋影響字母組(\w\W)以及字邊界行為(\b\B)。
3 re.M 使$匹配一行的結尾(而不僅僅是字串的結尾),並使^匹配任何行的開始(而不僅僅是字串的開頭)。
4 re.S 使一個句點(.)匹配任何字元,包括換行符。
5 re.U 根據Unicode字元集解釋字母。 此標誌影響\w\W\b\B的行為。
6 re.X 允許「cuter」正規表示式語法。 它忽略空格(除了一個集合[]內部,或者用反斜槓跳脫),並將未跳脫的#作為註釋標記。

6.正則表達模式

除了控制字元(+ ? . * ^ $ ( ) [ ] { } | \),所有字元都與其自身匹配。 可以通過使用反斜杠將其轉換為控制字元。

7.正規表示式範例

字元常數

編號 範例 說明
1 python 匹配「python」。

字元類

編號 範例 說明
1 [Pp]ython 匹配「Python」或「python」
2 rub[ye] 匹配「ruby」或「rube」
3 [aeiou] 匹配任何一個小寫元音
4 [0-9] 匹配任何數位; 如[0123456789]
5 [a-z] 匹配任何小寫ASCII字母
6 [A-Z] 匹配任何大寫的ASCII字母
7 [a-zA-Z0-9] 匹配上述任何一個
8 [^aeiou] 匹配除小寫元音之外的任何東西
9 [^0-9] 匹配數位以外的任何東西

特殊字元類

編號 範例 說明
1 . 匹配除換行符以外的任何字元
2 \d 匹配數位:[0-9]
3 \D 匹配非數位:[^0-9]
4 \s 匹配空格字元:[\t\r\n\f]
5 \S 匹配非空格:[^\t\r\n\f]
6 \w 匹配單字字元: [A-Za-z0-9_]
7 \W 匹配非單字字元: [A-Za-z0-9_]

重複匹配

編號 範例 說明
1 ruby? 匹配「rub」或「ruby」:y是可選的
2 ruby* 匹配「rub」加上0個以上的y
3 ruby+ 匹配「rub」加上1個或更多的y
4 \d{3} 完全匹配3位數
5 \d{3,} 匹配3位或更多位數位
6 \d{3,5} 匹配3,4或5位數

非貪婪重複

這匹配最小的重複次數 -

編號 範例 說明
1 <.*> 貪婪重複:匹配「<python> perl>
2 <.*?> 非貪婪重複:在「<python> perl」中匹配「<python>

用圓括號分組

編號 範例 說明
1 \D\d+ 沒有分組:+重複\d
2 (\D\d)+ 分組:+重複\D\d
3 ([Pp]ython(,)?)+ 匹配「Python」,「Python,python,python」等

反向參照

這與以前匹配的組再次匹配 -

編號 範例 說明
1 ([Pp])ython&\1ails 匹配python和pails或Python和Pails
2 (['"])[^\1]*\1 單引號或雙引號字串。\1匹配第一個分組匹配。 \2匹配任何第二個分組匹配等

備擇方案

  • python|perl - 匹配「python」或「perl」
  • rub(y|le) - 匹配 「ruby」 或 「ruble」
  • Python(!+|\?) - 「Python」後跟一個或多個! 還是一個?

錨點

這需要指定匹配位置。

編號 範例 說明
1 ^Python 在字串或內部行的開頭匹配「Python」
2 Python$ 在字串或內部行的結尾匹配「Python」
3 \APython 在字串的開頭匹配「Python」
4 Python\Z 在字串的末尾匹配「Python」
5 \bPython\b 在字詞的邊界匹配「Python」
6 \brub\B \B是非字詞邊界:在「rube」和「ruby」中匹配「rub」,而不是單獨匹配
7 Python(?=!) 匹配「Python」,如果跟著感嘆號。
8 Python(?!!) 匹配「Python」,如果沒有感嘆號後面。

帶括號的特殊語法

編號 範例 說明
1 R(?#comment) 匹配「R」。其餘的都是注釋
2 R(?i)uby 匹配「uby」時不區分大小寫
3 R(?i:uby) 同上
4 `rub(?:y le))` 僅組合而不建立\1反向參照