Python 正規表達式 (re)

Python 正規表達式(Python Regex)

這篇 Python 正規表達式教學將帶你用「模式」描述文字:找出所有 Email、驗證手機號碼格式、批次取代——字串方法做不到的模糊比對,正規表達式(regex)都能做。內建 re 模組就夠用。

先記住一個鐵則:regex 模式一律寫成 raw string(r"...",避免反斜線被 Python 先吃掉一層。

常用語法速查

語法意義範例
\d一個數字\d\d 配兩位數
\w字母、數字、底線
\s空白字元
.任意一個字元
+前面的東西 1 次以上\d+ 一串數字
*0 次以上
?0 或 1 次
{n}恰好 n 次\d{4} 四位數
[abc]a 或 b 或 c[0-9]\d
^ / $開頭/結尾
()分組擷取

re 的四個主力函式

函式用途回傳
re.search(p, s)找第一個符合Match 物件或 None
re.findall(p, s)找出全部List
re.sub(p, new, s)取代新字串
re.match(p, s)只從開頭比對Match 物件或 None
import re

text = "訂單編號 A123 與 B456 已出貨"

m = re.search(r"[A-Z]\d{3}", text)
print(m.group())                       # 第一個符合

print(re.findall(r"[A-Z]\d{3}", text)) # 全部
print(re.sub(r"\d", "*", text))        # 數字遮罩

執行輸出:

A123
['A123', 'B456']
訂單編號 A*** 與 B*** 已出貨

實戰一:擷取 Email

import re

text = "聯絡方式:alice@test.com 或 bob.chen@company.com.tw"

emails = re.findall(r"[\w.]+@[\w.]+\.\w+", text)
print(emails)

執行輸出:

['alice@test.com', 'bob.chen@company.com.tw']

實戰二:驗證台灣手機號碼

台灣手機是 09 開頭共 10 碼。驗證「整個字串」要用 ^...$ 鎖頭尾:

import re

def is_phone(s):
    return re.search(r"^09\d{8}$", s) is not None

print(is_phone("0912345678"))
print(is_phone("0912-345-678"))   # 有橫線,不符
print(is_phone("091234567"))      # 只有 9 碼

執行輸出:

True
False
False

要接受橫線格式,模式改成 r"^09\d{2}-?\d{3}-?\d{3}$"-? 表示橫線可有可無)。

分組擷取:()

用括號把想要的部分框起來,group(1)group(2) 分別取出:

import re

log = "2026-06-05 14:30 ERROR 資料庫連線逾時"

m = re.search(r"(\d{4}-\d{2}-\d{2}) \d{2}:\d{2} (\w+)", log)
if m:
    print("日期:", m.group(1))
    print("等級:", m.group(2))

執行輸出:

日期: 2026-06-05
等級: ERROR

常見錯誤

1. 忘記 raw string

"\d" 在一般字串裡有時能動、有時不能(如 \b 會變成退格字元),錯起來極難查。模式永遠寫 r"...",不用記哪些字元有問題。

2. match 與 search 搞混

re.match 只從字串「開頭」比對,目標在中間就回 None。日常九成情況用 searchfindall

3. AttributeError: ‘NoneType’ object has no attribute ‘group’

search 沒找到回傳 None,直接 .group() 就爆炸。先檢查:if m: 再取值。

4. .* 貪婪比對抓太多

.* 會盡量吃到最長;想要「最短符合」用 .*?。例如從 <b>A</b><b>B</b> 抓標籤內容,<b>(.*)</b> 會抓到 A</b><b>B<b>(.*?)</b> 才是 AB

總結

模式一律 r"...";四主力 search(找一個)、findall(找全部)、sub(取代)、match(限開頭);驗證整串鎖 ^...$、擷取局部用 () 分組;search 回 None 先判斷再 group。正規表達式語法是跨語言通用的,學一次到處用。下一篇是第四階段壓軸:Generator 與 Decorator。

延伸閱讀