Regular expression 描述 text pattern。在 data cleaning 裡主要做三件事:驗證 shape、抽取 component、轉換已知 representation。問題通常發生在把「形狀 match」誤當成「語意正確」。
分層讀 pattern
IPv4-like shape:
^(\d{1,3}\.){3}\d{1,3}$
^、$anchor 整個 value;\d{1,3}匹配 1–3 個 digit;\.匹配 literal dot;{3}重複 grouped prefix 三次。
它也接受 999.999.999.999,所以只驗證 syntax,沒有驗 numeric domain。四段 parse 完後,仍要分別檢查 0..255。
白話來說: Regex 能認出信封上地址的形狀,不能證明那個地址真的存在。
Match、extract、replace 是不同 operation
import re
raw = "2026/9/7"
m = re.fullmatch(r"(\d{4})/(\d{1,2})/(\d{1,2})", raw)
if m:
year, month, day = map(int, m.groups())
Extraction 之後要用 date library 驗證月份天數和 leap year,確認後才能輸出 2026-09-07。
Replacement 也要只處理 captured component:
re.sub(r"^([^,]+),\s*([^,]+)$", r"\2 \1", "Lin, Johnny")
只有 source convention 明確時這才安全;人名並不普遍等於兩個 comma-separated token。
常見陷阱
| 陷阱 | 症狀 | 改法 |
|---|---|---|
| 沒有 anchor | Invalid text 裡一小段 valid 就通過 | Validation 使用 full match |
| Greedy wildcard | Group 吃掉太多內容 | 明確 delimiter 或 non-greedy |
| Catastrophic backtracking | 特定 input 令 runtime 暴增 | 簡化 nested repetition、限制長度 |
| 一個超大 pattern | 無法 review 與解釋 | 分階段 parse、使用 named group |
| 假設 engine 相同 | 換工具後行為不同 | 記錄 flavor 與 flag |
Unicode 也會影響 \w、case folding 與 character class。Dataset 有 accent、非拉丁文字或 composed/decomposed form 時,都要加 fixture。
Mass edit 前先建 test matrix
| Case | Input | Expected |
|---|---|---|
| Normal | john@example.com |
accept |
| Boundary | 一字元 local part | policy 允許則 accept |
| Malformed | 缺 domain | reject |
| Near miss | 尾端空白或 comment | 明確 normalize 或 reject |
| Adversarial | 很長的重複 text | 必須快速結束 |
把例子和 cleaning rule 放在一起。沒有 positive/negative fixture 的 regex,只是沒文件的猜測。
何時不要再用 regex
Nested format、CSV quoting、JSON、URL、date 與 programming-language syntax 應交給 parser;identity、geography 要用 reference data 或 business rule。Regex 適合留在 boundary:先抽 candidate,或在進入強驗證前排除不可能的 shape。
複習卡
- Validation pattern 要 anchor 全值。
- Syntax match 與 domain/semantic validation 分開。
- 先 extract component,驗證後才 canonicalize。
- 記錄 regex flavor、flag 與 Unicode assumption。
- 測 valid、invalid、boundary、near-miss、adversarial input。
- Format 有 nested grammar 時,優先用真正 parser。