Python 速查手冊

12.1 正規運算式 re

正規運算式 (regular expression) 常用在對文件進行解析,例如做網路爬蟲去爬網路上的 HTML 文件,從中取得所欲取得之資訊,或是針對文件檔案進行處理。 Python 中做正規運算式的模組為 re ,首先要設定好配對形式 (pattern) 字串 (string) ,然後以該配對形式字串與所欲處理之字串利用 re 中相關功能的函數 (function) 進行處理。

配對形式字串通常會用以 r 開始的原始字串 (raw string) ,例如 r"str" 。此外,配對形式字串需要用到很多中介字元 (metacharacter) ,如下

. ^ $ * + ? { } [ ] \ | ( )
使用原始字串的原因是避免在字串中出現過多的反斜線,因為反斜線在字串中預設為跳脫序列 (escape sequence) ,像是 "\\\\" 為反斜線 \ 的配對形式字串。

下表為中介字元的說明

中介字元說明
.除了新行符號外的任何字元,例如 '.' 配對除了 '\n' 之外的任何字元。
^字串開頭的子字串或排除指定字元或群組,例如 'a[^b]c' 配對除了 'abc' 之外的任何 a 開頭 c 結尾的三字元組合。
$字串結尾的子字串,例如 'abc$' 配對以 'abc' 結尾的字串。
*單一字元或群組出現任意次數,例如 'ab*' 配對 'a' 、 'ab' 或 'abb' 等等。
+單一字元或群組出現至少一次,例如 'ab+' 配對 'ab' 或 'abb' 等等。
?單一字元或群組 0 或 1 次,例如 'ab+' 配對 'a' 或 'ab' 。
{m,n}單一字元或群組的 m 到 n 倍數,例如 'a{6}' 為連續六個 'a' , 'a{3,6}' 為三到六個 'a' 。
[]對中括弧內的字元形成集合,例如 '[a-z]' 為所有英文小寫字母。
\特別序列的起始字元。
|單一字元或群組的或,例如 'a|b' 為 'a' 或 'b' 。
()對小括弧內的字元形成群組。

以下為特別序列的說明

特別序列說明
\number群組的序數
\A字串的開頭字元。
\b作為單字的界線字元,例如 r'\bfoo\b' 配對 'foo' 或 'bar foo baz' 。
\B作為字元的界線字元,例如 r'py\B' 配對 'python' 或 'py3' 。
\d數字,從 0 到 9 。
\D非數字。
\s各種空白符號,包括新行符號 \n 。
\S非空白符號。
\w任意文字字元,包括數字。
\W非文字字元,包括空白符號。
\Z字串的結尾字元。

re 中有很多函數,以下列舉一些常用的函數

函數說明
compile(pattern)以配對形式字串 pattern 當參數,回傳 re.compile() 物件。
search(pattern, string, flags=0)從 string 中找尋第一個配對形式字串 pattern ,找到回傳配對物件,沒有找到回傳 None 。
match(pattern, string, flags=0)判斷配對形式字串 pattern 是否與 string 的開頭相符,如果相符就回傳配對物件,不相符就回傳 None 。
fullmatch(pattern, string, flags=0)判斷 string 是否與配對形式字串 pattern 完全相符,如果完全相符就回傳配對物件,不完全相符就回傳 None 。
split(pattern, string, maxsplit=0, flags=0)將 string 以配對形式字串 pattern 拆解,結果回傳拆解後的串列。
findall(pattern, string, flags=0)從 string 中找到所有的 pattern ,結果回傳所有 pattern 的串列。
finditer(pattern, string, flags=0)從 string 中找到所有的 pattern ,結果回傳所有 pattern 的迭代器。
sub(pattern, repl, string, count=0, flags=0)依據 pattern 及 repl 對 string 進行處理,結果回傳處理過的新字串。
subn(pattern, repl, string, count=0, flags=0)依據 pattern 及 repl 對 string 進行處理,結果回傳處理過的序對。
escape(pattern)將 pattern 中的特殊字元加入反斜線,結果回傳新字串。
purge()清除正規運算式的內部緩存。
以上參數 flag 可依據需要用 re 的內建常數進行設定,細節請參考官方文件的 The Python Standard Library - 6.2. re — Regular expression operations
re.compile() 物件的方法大致與以上函數類似。

其中配對物件 (match object) 有以下常用的方法

方法說明
group([group1, ...])回傳依據配對形式字串所符合的子字串。
groups(default=None)回傳依據配對形式字串所符合的序對。
groupdict(default=None)回傳依據配對形式字串所符合的字典。
start([group])回傳依據配對形式字串所符合的起始索引值。
end([group])回傳依據配對形式字串所符合的結束索引值。
span([group])回傳 (m.start(group), m.end(group)) 。

由於配對物件的布林值為 true ,而 search()match() 等函數在沒有得到配對結果的時候會回傳 None ,因此可把 search()match() 等當成布林函數,如果回傳為真才進行處理,例如以下程式可判斷是否為 Python 檔案

import sys
import re

try:
    filename = sys.argv[1]
    pattern = r"[a-zA-Z0-9]+(.py)"
    if re.fullmatch(pattern, filename):
        print("是Python檔案..")
    else:
        print("不是Python檔案..")
except:
    print("未提供檔案名稱..")

#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:redemo.py
# 功能:示範 re 模組
# 作者:張凱慶

於命令列執行以上程式

$ python3 redemo.py test.py
是Python檔案..
$

這裡, filename 是利用 sys 模組取得 python 指令之後接的命令列參數, argv[0] 為所執行的 Python 模組檔案,因此 argv[1] 為模組檔案後的參數,也就是執行模組檔案後空一格所接的文字,由以上命令列執行接的是 test.py

filename = sys.argv[1]

下一行配對字串是所有英文字母及數字的組合,加上 .py 的副檔名

pattern = r"[a-zA-Z0-9]+(.py)"

最後用 if 陳述利用 fullmatch() 函數判斷 patternfilename 是否完全吻合,然後印出相對應的訊息

if re.fullmatch(pattern, filename):
如果是英文字母與數字以外的 Python 檔案名稱,用此例的程式碼都會判斷為「不是Python檔案..」。

上一頁:單元 12 - 標準程式庫導覽
Python 速查手冊 - 目錄
下一頁: 12.2 時間日期處理 datatime
回 Python 教材首頁