Python 的 re 模組提供兩種使用正規表達式的方式:直接呼叫模組函式(如 re.match())或先用 re.compile() 預先編譯正規表達式再使用。本文說明 re.compile() 的用法和其優勢。
兩種使用方式比較
方式一:直接使用模組函式
1
2
3
4
5
6
7
8
|
import re
text = "Hello, World! 123"
# 每次呼叫都會重新編譯正規表達式
result = re.match(r'\d+', text)
result2 = re.search(r'\d+', text)
result3 = re.findall(r'\d+', text)
|
方式二:使用 re.compile() 預先編譯
1
2
3
4
5
6
7
8
9
10
11
|
import re
text = "Hello, World! 123"
# 預先編譯,建立 Pattern 物件
pattern = re.compile(r'\d+')
# 使用 Pattern 物件執行匹配
result = pattern.match(text)
result2 = pattern.search(text)
result3 = pattern.findall(text)
|
re.compile() 的優勢
1. 效能提升(最主要原因)
當同一個正規表達式需要重複使用多次時,re.compile() 可以顯著提升效能。Python 的 re 模組雖然有內建快取,但快取大小有限(預設 512 個),compile() 可以確保編譯結果被保留。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import re
import time
data_list = ["abc123", "def456", "ghi789"] * 100000
# 方式一:每次重新解析(較慢)
start = time.time()
for text in data_list:
re.search(r'\d+', text)
print(f"直接使用: {time.time() - start:.3f}s")
# 方式二:預先編譯(較快)
pattern = re.compile(r'\d+')
start = time.time()
for text in data_list:
pattern.search(text)
print(f"compile後: {time.time() - start:.3f}s")
|
2. 程式碼更清晰易讀
將正規表達式統一定義在程式頂部,方便集中管理和修改:
1
2
3
4
5
6
7
8
9
10
11
12
|
import re
# 集中定義所有 pattern
EMAIL_PATTERN = re.compile(r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}')
PHONE_PATTERN = re.compile(r'\d{2,4}-\d{3,4}-\d{4}')
DATE_PATTERN = re.compile(r'\d{4}-\d{2}-\d{2}')
def extract_info(text):
email = EMAIL_PATTERN.search(text)
phone = PHONE_PATTERN.search(text)
date = DATE_PATTERN.search(text)
return email, phone, date
|
3. 支援旗標(Flags)設定
1
2
3
4
5
6
7
8
9
|
import re
# 忽略大小寫 + 多行模式
pattern = re.compile(r'^hello', re.IGNORECASE | re.MULTILINE)
texts = ["Hello World", "hello python", "HELLO everyone"]
for text in texts:
if pattern.match(text):
print(f"匹配: {text}")
|
常用方法
re.compile() 回傳的 Pattern 物件支援以下方法:
| 方法 |
說明 |
pattern.match(string) |
從字串開頭開始匹配 |
pattern.search(string) |
搜尋字串中任意位置的匹配 |
pattern.findall(string) |
找出所有匹配,回傳串列 |
pattern.finditer(string) |
找出所有匹配,回傳迭代器 |
pattern.sub(repl, string) |
取代匹配的字串 |
pattern.split(string) |
以匹配結果分割字串 |
何時使用 re.compile()
- 應該使用:同一個正規表達式需要重複使用(迴圈、多次呼叫)
- 可以不用:只在一個地方用一次,直接
re.search() 即可,程式碼更簡潔