正則表達式是文本處理的瑞士軍刀。.NET 框架提供了功能強大、與 Perl 5 兼容的正則引擎,核心類位於 System.Text.RegularExpressions。本文系統講解 Regex、Match、MatchCollection、Group、Capture 五大核心類的協作機制與實戰模式。
Regex (不可變模式)
├─ Match(string input) → Match (首次匹配)
├─ Matches(string input) → MatchCollection (所有非重疊匹配)
├─ Replace/Split/IsMatch... → 便捷靜態方法
Match
├─ Success / Index / Length / Value
├─ Groups → GroupCollection (捕獲組)
└─ Captures → CaptureCollection (單組多次捕獲)
Group (繼承 Capture)
├─ Captures → CaptureCollection (量詞導致的多次捕獲)
└─ Name / Index / Length / Value
Capture
├─ Index / Length / Value
// 實例方法 (推薦複用)
var regex = new Regex(@"\d{4}-\d{2}-\d{2}", RegexOptions.Compiled);
// 靜態方法 (一次性使用)
Regex.IsMatch(input, pattern);
RegexOptionsCompiled:編譯為 IL,首次慢但執行快,適合高頻複用。IgnoreCase、Multiline、Singleline、ExplicitCapture (僅捕獲命名組)。CultureInvariant:忽略文化差異,提升性能。
var m = regex.Match("Date: 2024-01-15");
if (m.Success) {
Console.WriteLine($"Found at {m.Index}: {m.Value}"); // Found at 6: 2024-01-15
}
var mc = regex.Matches("2024-01-15, 2023-12-01");
foreach (Match m in mc) {
Console.WriteLine($"{m.Value} @ {m.Index}");
}
// 2024-01-15 @ 0
// 2023-12-01 @ 12
注意:MatchCollection 為惰性評估,Count 會觸發全量匹配。大文本首選 Regex.Matches(...).Cast<Match>() 流式處理。
var r = new Regex(@"(a(b))c");
var m = r.Match("abdabc");
Console.WriteLine(m.Groups.Count); // 3 (Group 0: 整個匹配, Group 1: (a(b)), Group 2: (b))
var r = new Regex(@"(Abc)+");
var m = r.Match("XYZAbcAbcAbcXYZAbcAb");
// Group 0: AbcAbcAbc (整個匹配)
// Group 1: 最後一次捕獲 "Abc"
// Group 1.Captures: ["Abc", "Abc", "Abc"] (三次捕獲)
foreach (Capture c in m.Groups[1].Captures) {
Console.WriteLine($"{c.Value} @ {c.Index}");
}
// Abc @ 3
// Abc @ 6
// Abc @ 9
(?:...) 與 ExplicitCapture(?:sub):分組但不捕獲,不佔用 Group 槽位,無 Captures 開銷。RegexOptions.ExplicitCapture:全局禁用隱式捕獲,僅 (?<name>...) 命名組有效。| 場景 | 建議 |
|---|---|
| 高頻複用模式 | static readonly Regex _r = new Regex(p, RegexOptions.Compiled); |
| 超大文本流式處理 | foreach (Match m in regex.Matches(hugeText)) yield return m; 避免全量載入 |
| 替換需動態計算 | regex.Replace(input, m => ComputeReplacement(m)); |
| 分割保留分隔符 | regex.Split(input) 配合 (?=(...)) 先行斷言 |
| 避免災難性回溯 | 使用 RegexOptions.NonBacktracking (.NET 7+) 或原子組 (?>...) |
// Email 簡易驗證
^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
// URL
^(https?|ftp)://[^\s/$.?#].[^\s]*$
// 中文
[\u4e00-\u9fa5]
// IP 地址
\b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b
正則表達式威力巨大,但「寫時只讀、改時淚流」。複雜邏輯優先考慮解析器組合子或專用庫 (如 HTML 用 AngleSharp, JSON 用 System.Text.Json),保持代碼可維護性。