Python 正規表達式 (Regex)
Python 的 re 模組提供了對正規表達式 (Regular Expression) 的支援。正規表達式是一種強大的文字搜尋和處理工具。
本篇專注於 Python
re 模組的用法。關於正規表達式的詳細語法(如符號意義),請參考 正規表達式教學。常用函數
要使用正規表達式,首先匯入模組:
import re
re.search() - 搜尋第一個相符
搜尋字串中「任意位置」的第一個相符項目。
text = "The price is $99.99"
match = re.search(r'\$\d+\.\d+', text)
if match:
print("Found:", match.group()) # Found: $99.99
print("Index:", match.span()) # Index: (13, 19)
else:
print("Not found")
re.match() - 從頭開始比對
只檢查字串的 開頭 是否符合。
text = "The price is $99.99"
# 失敗,因為開頭是 "The" 不是數字
print(re.match(r'\d+', text)) # None
# 成功
print(re.match(r'The', text)) # <re.Match object; span=(0, 3), match='The'>
re.findall() - 搜尋所有相符
回傳所有相符項目的字串列表 (List)。
text = "Apple: 10, Banana: 20, Orange: 30"
numbers = re.findall(r'\d+', text)
print(numbers) # ['10', '20', '30']
re.sub() - 取代
將符合樣式的部分取代為其他字串。
text = "User: private@example.com, Admin: root@example.com"
# 將 email 隱藏
result = re.sub(r'[\w\.-]+@[\w\.-]+', '***', text)
print(result)
# User: ***, Admin: ***
Match 物件
當 search 或 match 成功時,回傳一個 Match 物件:
text = "My email is alice@example.com"
match = re.search(r'(\w+)@(\w+\.com)', text)
if match:
print(match.group()) # 完整相符: alice@example.com
print(match.group(1)) # 第一個群組: alice
print(match.group(2)) # 第二個群組: example.com
print(match.groups()) # 所有群組: ('alice', 'example.com')
編譯正規表達式
如果你需要在迴圈中重複使用同一個樣式,建議使用 re.compile() 預先編譯,效能會更好。
# 編譯樣式
email_pattern = re.compile(r'[\w\.-]+@[\w\.-]+')
users = [
"user1@example.com",
"invalid-email",
"user2@test.org"
]
for user in users:
if email_pattern.match(user):
print(f"Valid: {user}")
else:
print(f"Invalid: {user}")
常用 Flags
可以使用 Flags 改變比對行為:
re.IGNORECASE(re.I): 忽略大小寫re.MULTILINE(re.M): 多行模式,影響^和$的行為re.DOTALL(re.S): 讓.也可以比對換行符號
text = """Line 1
Line 2"""
# 預設 . 不包含換行
print(re.findall(r'Line 1.Line 2', text)) # []
# 使用 DOTALL
print(re.findall(r'Line 1.Line 2', text, re.DOTALL)) # ['Line 1\nLine 2']
# 忽略大小寫
print(re.findall(r'line', "Line line LINE", re.IGNORECASE)) # ['Line', 'line', 'LINE']
分組與命名
使用 (?P<name>...) 可以為群組命名,讓程式碼更易讀:
pattern = r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'
match = re.search(pattern, "2024-12-25")
if match:
print(match.group("year")) # 2024
print(match.group("month")) # 12
print(match.group("day")) # 25