正規運算式 (regular expression) 常用在對文件進行解析,例如做網路爬蟲去爬網路上的 HTML 文件,從中取得所欲取得之資訊,或是針對文件檔案進行處理。 Python 中做正規運算式的模組為 re ,首先要設定好配對形式 (pattern) 字串 (string) ,然後以該配對形式字串與所欲處理之字串利用 re 中相關功能的函數 (function) 進行處理。
配對形式字串通常會用以 r 開始的原始字串 (raw string) ,例如 r"str" 。此外,配對形式字串需要用到很多中介字元 (metacharacter) ,如下
下表為中介字元的說明
中介字元 | 說明 |
---|---|
. | 除了新行符號外的任何字元,例如 '.' 配對除了 '\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() | 清除正規運算式的內部緩存。 |
其中配對物件 (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() 函數判斷 pattern 與 filename 是否完全吻合,然後印出相對應的訊息
if re.fullmatch(pattern, filename):
相關教學影片