Dev Tools
回文章列表·9 min

Regex 深入解析:capture groups、lookaround、災難性回溯與跨語言差異

regex 是 QA / SRE / 後端工程師每天用、但永遠覺得自己不夠熟的東西。這篇整理我這幾年遇過真正會用到的進階技巧,以及那些「為什麼我的 regex 把瀏覽器卡死」的真實案例。

Capture group vs non-capturing vs named

三種寫法都在用括號,但意義不同:

  • () Capture group:抓出來,可以用 $1$2 引用
  • (?:) Non-capturing group:只分組,不抓 — 效能比 () 略好,複雜 regex 應該大量用
  • (?<name>) Named group:抓出來且能用名字引用 — 可讀性大勝,維護時不會數錯位置

例:抓 email

  • 笨寫法:(\w+)@(\w+)\.(\w+),後續用 $1 $2 $3 — 一個月後回來看完全不知道哪個是什麼。
  • 好寫法:(?<user>\w+)@(?<host>\w+)\.(?<tld>\w+),用 groups.user 直接懂。

Lookahead / lookbehind:不消耗字元的條件

Lookaround 在 regex 引擎內查條件但不前進游標,適合需要「同時滿足多條件」的場景:

  • (?=...) Positive lookahead:後面必須是某東西
  • (?!...) Negative lookahead:後面不能是某東西
  • (?<=...) Positive lookbehind:前面必須是某東西
  • (?<!...) Negative lookbehind:前面不能是某東西

實用例:抓密碼但要求至少一個數字 + 一個大寫字母

^(?=.*\d)(?=.*[A-Z]).{8,}$

三個 lookahead 並聯,沒有任何字元被「消耗」,只是檢查條件。比寫多條正規表達式組合判斷簡潔太多。

災難性回溯:會把瀏覽器卡死的寫法

Nested quantifier(巢狀量詞)幾乎一定踩雷。經典 anti-pattern:(a+)+ (a*)* (a|a)*

(a+)+baaaaaaaaaaaaaaaaa 為例:regex 引擎要試所有「a 怎麼分組」的排列組合才放棄,複雜度 O(2^n)。輸入只要再長一點點,瀏覽器就凍住(我自己中過 — 用 30 字元測試字串跑了 8 秒)。

怎麼避免:

  1. atomic group (?>...)(JS 不支援,Node ≥ 16 才支援,Java / .NET 支援)
  2. possessive quantifier ++ *+(同樣 JS 不支援)
  3. 檢查你的 quantifier 沒有重疊((\w+)+ → 直接用 \w+)
  4. 限制輸入長度(本站工具設 100,000 字元上限就是為了這個)

JS 圈通常用 (3) + (4),從寫法上避免問題。

JavaScript vs Python:常被踩的差異

  • 行首行尾:JS 沒有 \A \Z,要用 ^ $ + m flag
  • Unicode:JS 要加 u flag 才支援 \p{Letter},Python 預設就支援
  • Lookbehind:舊版 Safari < 16.4 完全不支援 lookbehind,你寫了線上就掛。一定要在 production 加 try / catch fallback
  • re vs regex 模組(Python):標準 re 不支援 lookbehind 變長,要裝 regex 模組
  • Sticky flag y:JS 有、Python 沒有 — 從固定位置開始 match,寫 lexer 用得到

QA 真實場景

我自己常用 regex 的時候:

  • nginx access log 解析:抓 IP、status、response time → 算 p95(可以接到 百分位計算工具)
  • API response body 驗證:Robot Framework 的 Should Match RegexpShould Contain 強太多
  • 產測試資料:(\d{4}) (\d{4}) (\d{4}) (\d{4}) 這種格式驗證,要先確認自己產的 信用卡測試資料 符合
  • Selenium 動態元素 ID:抓 userdata-([a-f0-9]{8}) 這種隨機後綴
  • 錯誤訊息分類:把 stack trace 用 regex 抓出 file path + line number 統計最常出問題的模組

想試?把這篇用到的所有 pattern 貼到 Regex 工具 跑,即時看命中。最常出意外的就是 lookbehind 在 Safari 上掛掉那個。

搭配工具
Regex builder 即時測試
開啟工具