正則表達式 是文本處理的瑞士軍刀。半年前我為系統學習 Regex 翻譯了 RegexBuddy 官方教程(作者 Jan Goyvaerts),公認最淺顯易懂的入門資料。本文保留「深入淺出」之名,因其確切傳達了「由淺入深、知其然更知其所以然」的學習體驗。版權歸原作者,轉載請註明出處。
Regex(Regular Expression)是一種「描述文本模式」的語言。引擎根據模式在目標字串中搜尋匹配。本教程聚焦 Perl 5 風格引擎(PCRE、.NET、Java、JavaScript 等多數現代引擎均屬此類)。
a 匹配第一個 'a';cat 匹配連續 'c' 'a' 't'。Regex.Match.NextMatch())。11 個保留字元:[ ] \ ^ $ . | ? * + ( )。若要匹配字面值,**必須轉義**(前加 \)。
| 元字元 | 含義 | 範例 |
|---|---|---|
. | 任意單一字元(除換行) | c.t 匹配 cat, cot, c3t |
\d | 數字 [0-9] | \d{3}-\d{4} 電話號碼 |
\w | 單字字元 [a-zA-Z0-9_] | \w+ 匹配單字 |
\s | 空白字元 | \s+ 多個空格 |
^ | 行首(多行模式下) | ^Start |
$ | 行尾(多行模式下) | End$ |
[abc] | 字元集合 | [aeiou] 元音 |
[^abc] | 排除字元集合 | [^0-9] 非數字 |
| | 或邏輯 | cat|dog |
() | 分組/捕獲 | (\d{4})-(\d{2}) 年-月 |
? | 0 或 1 次 | colou?r color/colour |
* | 0 次或多次 | ab*c ac, abc, abbc... |
+ | 1 次或多次 | \d+ 至少一位數字 |
{n,m} | 量詞範圍 | \d{2,4} 2-4 位數字 |
\b 單字邊界;\B 非單字邊界。(?=pattern) 正向前瞻(零寬斷言):\d+(?=px) 匹配後面跟 px 的數字,但不消耗 px。(?!pattern) 負向前瞻:\d+(?!px) 匹配不跟 px 的數字。(?<=pattern) 正向後顧(固定寬度):(?<=\$)\d+ 匹配 $ 後的數字。(? 負向後顧。| 模式 | 行為 | 範例輸入 <tag>content</tag> |
|---|---|---|
<.+> | 貪婪:匹配最長 | 整串 <tag>content</tag> |
<.+?> | 惰性:匹配最短 | <tag> |
<.++> | 佔有優先:不回溯 | 失敗(因 . 匹配了 > 導致後面無法匹配) |
**實戰建議**:能用惰性/佔有優先就不用貪婪,大幅降低回溯導致的效能災難(ReDoS)。
(...) 捕獲組,編號從 1 開始;(?:...) 非捕獲組(不佔編號,效能稍好)。\1 \2... 在模式中反向引用;替換字串中用 $1 $2。(?<year>\d{4}),引用 \k<year> 或 ${year}。"\\\\d+" → Regex \\d+ → 匹配 \d)。使用原始字串字面值(C++11 R"(\d+)"、C# @"\d+"、Python r"\d+")。. 不匹配換行,除非啟用 Singleline/DOTALL 模式。^$ 預設匹配整字串首尾,多行模式下匹配行首尾。(a+)+、大量回溯模式。善用 atomic group (?>...) 或佔有優先量詞。\p{L} 匹配任意 Unicode 字母,\X 匹配擴展書寫字素簇。正則表達式看似晦澀,實則邏輯嚴密。掌握「字面、元字元、量詞、分組、斷言、貪婪/惰性」六大支柱,配合工具實戰演練,即能驾駭 90% 文本處理需求。記住:**可讀性優於炫技**,複雜模式請拆解註釋,善用 (?x) 忽略空白模式撰寫自文檔化 Regex。