Python 正則表示式



正則表示式是一種特殊的字元序列,它使用專門的語法(包含在模式中)來幫助您匹配或查詢其他字串或字串集。正則表示式通常稱為 regex 或 regexp。

通常,此類模式由字串搜尋演算法用於字串的“查詢”或“查詢和替換”操作,或用於輸入驗證。

資料科學專案中大規模文字處理需要對文字資料進行操作。許多程式語言(包括 Python)都支援正則表示式處理。Python 的標準庫為此目的提供了 **re** 模組。

由於 **re** 模組中定義的大多數函式都使用原始字串,因此讓我們首先了解什麼是原始字串。

原始字串

正則表示式使用反斜槓字元 ('\') 來表示特殊形式,或允許使用特殊字元而不呼叫它們的特殊含義。另一方面,Python 使用相同的字元作為跳脫字元。因此,Python 使用原始字串表示法。

如果在引號符號之前用 r 或 R 作字首,則字串變為原始字串。因此,'Hello' 是普通字串,而 r'Hello' 是原始字串。

>>> normal="Hello"
>>> print (normal)
Hello
>>> raw=r"Hello"
>>> print (raw)
Hello

在正常情況下,兩者之間沒有區別。但是,當跳脫字元嵌入到字串中時,普通字串實際上會解釋轉義序列,而原始字串不會處理跳脫字元。

>>> normal="Hello\nWorld"
>>> print (normal)
Hello
World
>>> raw=r"Hello\nWorld"
>>> print (raw)
Hello\nWorld

在上面的示例中,當列印普通字串時,跳脫字元 '\n' 會被處理以引入換行符。但是,由於原始字串運算子 'r',跳脫字元的效果不會根據其含義進行轉換。

元字元

大多數字母和字元只會匹配自身。但是,某些字元是特殊的元字元,並且不匹配自身。元字元是具有特殊含義的字元,類似於萬用字元中的 *。

以下是元字元的完整列表:

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

方括號符號 [ 和 ] 表示您希望匹配的一組字元。字元可以單獨列出,也可以作為字元範圍列出,用 '-' 分隔。

序號 元字元及描述
1

[abc]

匹配字元 a、b 或 c 中的任何一個
2

[a-c]

使用範圍表示相同的字元集。
3

[a-z]

僅匹配小寫字母。
4

[0-9]

僅匹配數字。
5

'^'

補充 [] 中的字元集。[^5] 將匹配除 '5' 之外的任何字元。

'\' 是一個轉義元字元。當它後面跟著各種字元時,它會形成各種特殊的序列。如果您需要匹配 [ 或 \,您可以用反斜槓在前面加上它們來消除它們的特殊含義:\[ 或 \\。

以下列出了以 '\' 開頭的此類特殊序列表示的預定義字元集:

序號 元字元及描述
1

\d

匹配任何十進位制數字;這等效於類 [0-9]。
2

\D

匹配任何非數字字元;這等效於類 [^0-9]。
3 **\s**匹配任何空白字元;這等效於類 [\t\n\r\f\v]。
4

\S

匹配任何非空白字元;這等效於類 [^\t\n\r\f\v]。
5

\w

匹配任何字母數字字元;這等效於類 [a-zA-Z0-9_]。
6

\W

匹配任何非字母數字字元。等效於類 [^a-zA-Z0-9_]。
7

.

匹配除換行符 '\n' 之外的任何單個字元。
8

?

匹配其左側模式的 0 次或 1 次出現
9

+

其左側模式的 1 次或多次出現
10

*

其左側模式的 0 次或多次出現
11

\b

單詞和非單詞之間的邊界,/B 與 /b 相反
12

[..]

匹配方括號中任意單個字元,[^..] 匹配方括號中不存在的任意單個字元。
13

\

用於特殊含義的字元,例如 \. 匹配句點,\+ 匹配加號。
14

{n,m}

匹配前面表示式的至少 n 次,至多 m 次出現。
15

a| b

匹配 a 或 b。

Python 的 re 模組提供了許多有用的函式,用於查詢匹配項、搜尋模式以及用其他字串替換匹配的字串等。

re.match() 函式

此函式嘗試使用可選的 flagsstring 的開頭匹配 RE pattern。以下是此函式的語法

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

以下是引數的描述:

序號 引數 & 描述
1

pattern

要匹配的正則表示式。

2

String

要搜尋的字串,將在字串開頭匹配模式。

3

Flags

可以使用按位或 (|) 指定不同的標誌。這些是修飾符,如下表所示。

re.match() 函式成功時返回一個match 物件,失敗時返回None。match 物件例項包含有關匹配的資訊:它從哪裡開始和結束,它匹配的子字串等。

match 物件的 start() 方法返回模式在字串中的起始位置,end() 返回結束位置。

如果找不到模式,則 match 物件為 None。

我們使用match 物件的group(num)groups() 函式來獲取匹配的表示式。

序號 Match 物件方法 & 描述
1 group(num=0) 此方法返回整個匹配項(或特定子組 num)
2 groups() 此方法以元組的形式返回所有匹配的子組(如果沒有,則為空)

示例

import re
line = "Cats are smarter than dogs"
matchObj = re.match( r'Cats', line)
print (matchObj.start(), matchObj.end())
print ("matchObj.group() : ", matchObj.group())

它將產生以下輸出

0 4
matchObj.group() : Cats

re.search() 函式

此函式使用可選的 flagsstring 中搜索 RE pattern 的第一次出現。以下是此函式的語法

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

以下是引數的描述:

序號 引數 & 描述
1

Pattern

要匹配的正則表示式。

2

String

要搜尋的字串,將在字串中的任何位置匹配模式。

3

Flags

可以使用按位或 (|) 指定不同的標誌。這些是修飾符,如下表所示。

re.search 函式成功時返回一個match 物件,失敗時返回none。我們使用match 物件的group(num)groups() 函式來獲取匹配的表示式。

序號 Match 物件方法 & 描述
1 group(num=0) 此方法返回整個匹配項(或特定子組 num)
2 groups() 此方法以元組的形式返回所有匹配的子組(如果沒有,則為空)

示例

import re
line = "Cats are smarter than dogs"
matchObj = re.search( r'than', line)
print (matchObj.start(), matchObj.end())
print ("matchObj.group() : ", matchObj.group())

它將產生以下輸出

17 21
matchObj.group() : than

匹配與搜尋

Python 提供了兩種基於正則表示式的不同基本操作,match 僅檢查字串開頭的匹配項,而search 檢查字串中任何位置的匹配項(這是 Perl 預設執行的操作)。

示例

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

re.findall() 函式

findall() 函式以字串或元組列表的形式返回字串中模式的所有不重疊匹配項。字串從左到右掃描,並按找到的順序返回匹配項。結果中包含空匹配項。

語法

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

引數

序號 引數 & 描述
1

Pattern

要匹配的正則表示式。

2

String

要搜尋的字串,將在字串中的任何位置匹配模式。

3

Flags

可以使用按位或 (|) 指定不同的標誌。這些是修飾符,如下表所示。

示例

import re
string="Simple is better than complex."
obj=re.findall(r"ple", string)
print (obj)

它將產生以下輸出

['ple', 'ple']

以下程式碼在 findall() 函式的幫助下獲取句子中的單詞列表。

import re
string="Simple is better than complex."
obj=re.findall(r"\w*", string)
print (obj)

它將產生以下輸出

['Simple', '', 'is', '', 'better', '', 'than', '', 'complex', '', '']

re.sub() 函式

使用正則表示式的最重要的re 方法之一是sub

語法

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

此方法將 string 中 RE pattern 的所有出現替換為 repl,除非提供了 max,否則將替換所有出現。此方法返回修改後的字串。

示例

import re
phone = "2004-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 : 2004-959-559
Phone Num : 2004959559

示例

以下示例使用 sub() 函式替換所有出現的 is 為 was 單詞:

import re
string="Simple is better than complex. Complex is better than complicated."
obj=re.sub(r'is', r'was',string)
print (obj)

它將產生以下輸出

Simple was better than complex. Complex was better than complicated.

re.compile() 函式

compile() 函式將正則表示式模式編譯成正則表示式物件,可以使用其 match()、search() 及其他方法進行匹配。

語法

re.compile(pattern, flags=0)

Flags

序號 修飾符 & 描述
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

允許使用“更簡潔”的正則表示式語法。它忽略空格(集合 [] 內除外,或被反斜槓轉義時除外),並將未轉義的 # 視為註釋標記。

序列:

prog = re.compile(pattern)
result = prog.match(string)

等效於:

result = re.match(pattern, string)

但是,當在一個程式中多次使用表示式時,使用 re.compile() 並儲存生成的正則表示式物件以供重用效率更高。

示例

import re
string="Simple is better than complex. Complex is better than complicated."
pattern=re.compile(r'is')
obj=pattern.match(string)
obj=pattern.search(string)
print (obj.start(), obj.end())

obj=pattern.findall(string)
print (obj)

obj=pattern.sub(r'was', string)
print (obj)

它將產生以下輸出:

7 9
['is', 'is']
Simple was better than complex. Complex was better than complicated.

re.finditer() 函式

此函式返回一個迭代器,對字串中 RE 模式的所有不重疊匹配項生成匹配物件。

語法

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

示例

import re
string="Simple is better than complex. Complex is better than complicated."
pattern=re.compile(r'is')
iterator = pattern.finditer(string)
print (iterator )

for match in iterator:
   print(match.span())

它將產生以下輸出

(7, 9)
(39, 41)

Python 正則表示式的用例

查詢所有副詞

findall() 匹配模式的所有出現,而不僅僅是 search() 的第一個出現。例如,如果作者想要查詢某些文字中的所有副詞,他們可能會以如下方式使用 findall():

import re
text = "He was carefully disguised but captured quickly by police."
obj = re.findall(r"\w+ly\b", text)
print (obj)

它將產生以下輸出

['carefully', 'quickly']

查詢以母音開頭的單詞

import re
text = 'Errors should never pass silently. Unless explicitly silenced.'
obj=re.findall(r'\b[aeiouAEIOU]\w+', text)
print (obj)

它將產生以下輸出

['Errors', 'Unless', 'explicitly']

正則表示式修飾符:選項標誌

正則表示式文字可以包含一個可選的修飾符來控制匹配的各個方面。修飾符指定為可選標誌。您可以使用異或 (|) 提供多個修飾符,如前面所示,並且可以使用以下其中一個表示:

序號 修飾符 & 描述
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

允許使用“更簡潔”的正則表示式語法。它忽略空格(集合 [] 內除外,或被反斜槓轉義時除外),並將未轉義的 # 視為註釋標記。

正則表示式模式

除控制字元(+ ? . * ^ $ ( ) [ ] { } | \) 外,所有字元都與其自身匹配。您可以透過在控制字元前面加上反斜槓來轉義它。

下表列出了 Python 中可用的正則表示式語法:

序號 模式 & 描述
1

^

匹配行首。

2

$

匹配行尾。

3

.

匹配除換行符外的任何單個字元。使用 m 選項允許它匹配換行符。

4

[...]

匹配括號中的任何單個字元。

5

[^...]

匹配括號中不存在的任何單個字元

6

re*

匹配前面表示式的 0 次或多次出現。

7

re+

匹配前面表示式的 1 次或多次出現。

8

re?

匹配前面表示式的 0 次或 1 次出現。

9

re{ n}

精確匹配前面表示式 n 次出現。

10

re{ n,}

匹配前面表示式的 n 次或多次出現。

11

re{ n, m}

匹配前面表示式的至少 n 次,至多 m 次出現。

12

a| b

匹配 a 或 b。

13

(re)

分組正則表示式並記住匹配的文字。

14

(?imx)

臨時啟用正則表示式中的 i、m 或 x 選項。如果在括號內,則僅影響該區域。

15

(?-imx)

臨時停用正則表示式中的 i、m 或 x 選項。如果在括號內,則僅影響該區域。

16

(?: re)

分組正則表示式而不記住匹配的文字。

17

(?imx: re)

臨時啟用括號內的 i、m 或 x 選項。

18

(?-imx: re)

臨時停用括號內的 i、m 或 x 選項。

19

(?#...)

註釋。

20

(?= re)

使用模式指定位置。沒有範圍。

21

(?! re)

使用模式否定指定位置。沒有範圍。

22

(?> re)

匹配不回溯的獨立模式。

23

\w

匹配單詞字元。

24

\W

匹配非單詞字元。

25

\s

匹配空格。等效於 [\t\n\r\f]。

26

\S

匹配非空格。

27

\d

匹配數字。等效於 [0-9]。

28

\D

匹配非數字。

29

\A

匹配字串開頭。

30

\Z

匹配字串結尾。如果存在換行符,則匹配換行符之前的字元。

31

\z

匹配字串結尾。

32

\G

匹配上次匹配結束的位置。

33

\b

在括號外匹配單詞邊界。在括號內匹配退格鍵 (0x08)。

34

\B

匹配非單詞邊界。

35

\n, \t, etc.

匹配換行符、回車符、製表符等。

36

\1...\9

匹配第 n 個分組子表示式。

37

\10

如果第 n 個分組子表示式已匹配,則匹配它。否則引用字元程式碼的八進位制表示。

正則表示式示例

字面字元

序號 示例 & 描述
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 匹配第二個組匹配的任何內容,依此類推。

備選方案

序號 示例 & 描述
1

python|perl

匹配 "python" 或 "perl"

2

rub(y|le)

匹配 "ruby" 或 "ruble"

3

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",但不是單獨的 "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 反向引用

廣告