.NET 基礎類庫提供 System.Text.RegularExpressions 命名空間,功能強大且兼容 Perl 5 語法。本文系統介紹核心類、靜態方法、匹配/替換/分組實戰,並匯總常用模式。
命名空間僅含 6 個類 + 1 個委托:
Capture / CaptureCollection:單次捕獲結果與集合。Group:分組捕獲結果 (繼承 Capture)。Match:單次匹配結果 (繼承 Group)。MatchCollection:匹配結果集合。MatchEvaluator:替換操作委托。Regex:編譯後正則實例,核心入口。Regex 靜態方法:Escape, IsMatch, Match, Matches, Replace, Split, Unescape。
// 簡單匹配
Match m = Regex.Match("abracadabra", "(a|b|r)+");
if (m.Success) Console.WriteLine(m.Value); // "abra"
// 簡單替換
string s = Regex.Replace("abracadabra", "abra", "zzzz"); // "zzzzcadzzzz"
// 複雜替換:去除首尾空格
string s2 = Regex.Replace(" abra ", @"^\s*(.*?)\s*$", "$1"); // "abra"
使用 @"" 字面量字符串避免雙重轉義。$1 代表第 1 組捕獲內容。
string text = "abracadabra1abracadabra2abracadabra3";
string pat = @"
( # Group 1 開始
abra # 匹配 abra
( # Group 2 開始 (可選)
cad
)? # Group 2 結束
) # Group 1 結束
+ # 重複 1 次或多次
";
Regex r = new Regex(pat, "x"); // "x" 選項忽略模式中的空白與註釋
Match m = r.Match(text);
while (m.Success) {
for (int i = 1; i < r.GetGroupNumbers().Length; i++) {
Group g = m.Groups[r.GetGroupNumbers()[i]];
Console.WriteLine($"Group{g.GroupNumber}=[{g.Value}]");
for (int j = 0; j < g.Captures.Count; j++) {
Capture c = g.Captures[j];
Console.WriteLine($" Capture{j}=[{c.Value}] Index={c.Index} Len={c.Length}");
}
}
m = m.NextMatch();
}
輸出展示 Group 1 有兩個 Capture (abracad, abra),Group 2 捕獲 cad。Group.Value 等於最後一個 Capture.Value。
foreach (Match m in Regex.Matches(...)) 迴圈中用 C# 代碼處理每個匹配 (如首字母大寫)。Regex.Replace(input, pattern, new MatchEvaluator(Handler)),邏輯封裝在委托中,模式更簡潔 (只匹配需處理部分)。兩者結合最佳:複雜邏輯用過程,純文本變換用表達式。
| 場景 | 模式 |
|---|---|
| 羅馬數字驗證 | ^m*(d?c{0,3}|c[dm])(l?x{0,3}|x[lc])(v?i{0,3}|i[vx])$ |
| 交換前兩詞 | (\S+)(\s+)(\S+) → 替換 $3$2$1 |
| 鍵值對解析 | (\w+)\s*=\s*(.*)\s*$ |
| 每行 80 字符 | .{80,} |
| 日期時間 (MM/dd/yy HH:mm:ss) | (\d+)/(\d+)/(\d+) (\d+):(\d+):(\d+) |
| 路徑用戶名替換 | \\user1\\ → \\user2\\ |
| URL 解碼 (%XX) | %([0-9A-Fa-f]{2}) |
| 刪除 C 註釋 | /\*.*?\*/ (選項 xs) |
| 去首尾空格 | ^\s+|\s+$ |
| \n 轉真換行 | \\n → \n |
| IPv4 驗證 | ^([01]?\d\d|2[0-4]\d|25[0-5])(\.([01]?\d\d|2[0-4]\d|25[0-5])){3}$ |
| 提取文件名 | ^.*\\ → 替換空 |
| 合併多行 | \s*\r?\n\s* → 空格 |
| 提取所有數字 | (\d+\.?\d*|\.\d+) |
| 全大寫單詞 | \b[^\Wa-z0-9_]+\b |
| 全小寫單詞 | \b[^\WA-Z0-9_]+\b |
| 首字母大寫單詞 | \b[^\Wa-z0-9_][^\WA-Z0-9_]*\b |
| HTML 鏈接提取 | <A[^>]*?HREF\s*=\s*['""]?([^'"">>]+)['""]?> (選項 si) |
編譯時需引用 System.Text.RegularExpressions.dll:csc /r:System.Text.RegularExpressions.dll foo.cs。