首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 正則表達式實戰:命名群組精準擷取 JSON 片段與 HTML 內容

     編輯:關於C語言

正則表達式是文字處理的瑞士刀,善用命名捕獲群組能讓程式碼更易讀、維護性更高。本文透過兩個實戰案例,示範如何在 C# 中撰寫高可讀性的 Regex 模式,精準萃取結構化資料。

案例一:從類 JSON 字串雙向擷取錯誤碼與資料區塊

目標字串

string raw = "ErrorCode:-1,Message:{\"UserId\":\"1000\",\"userName\":\"ZhangSan\"}";

需同時取得 -1 與完整 JSON 物件 {"UserId":"1000","userName":"ZhangSan"}。

關鍵技巧:同名命名群組 (?<key>...)

using System.Text.RegularExpressions;

string pattern = @"ErrorCode:(?<key>.*?),Message:\{(?<key>.*?)\}";
//                    ↑ 群組名 key          ↑ 同名群組 key (會合併捕獲)

Regex reg = new Regex(pattern);
Match match = reg.Match(raw);

if (match.Success)
{
    // Groups["key"].Captures 會依序保存兩個捕獲值
    var captures = match.Groups["key"].Captures;
    string errorCode = captures[0].Value;        // "-1"
    string jsonBlock = captures[1].Value;        // "UserId\":\"1000\",\"userName\":\"ZhangSan"
    
    // 若需完整 JSON 格式,自行補上大括號
    string fullJson = "{" + jsonBlock + "}";
    Console.WriteLine($"{errorCode} -- {fullJson}");
    // 輸出:-1 -- {"UserId":"1000","userName":"ZhangSan"}
}

核心語法解析

語法說明
(?<name>...)命名捕獲群組,可透過 Groups["name"] 存取
.*?非貪婪匹配:盡可能少吃字元,遇到後續 ,Message: 即停止
\{ / \}大括號為特殊字元,需跳脫
同名群組重複出現所有捕獲值會疊加在 Groups["name"].Captures 集合中,依出現順序索引

案例二:從 HTML 片段精準取出特定列表項目

來源 HTML

<td align="center"><ul>
  <li>查詢結果1:北京市 網通</li>
  <li>查詢結果2:北京市 網通</li>
  <li>查詢結果3:北京市 網通</li>
</ul></td>

目標:只取「查詢結果1」後的城市資訊 北京市 網通。

精準定位模式

string html = @"<td align=""center""><ul><li>查詢結果1:北京市 網通</li><li>查詢結果2:北京市 網通</li><li>查詢結果3:北京市 網通</li></ul></td>";

string pattern = @"<li>查詢結果1:(?<key>.*?)</li>";
//                     ↑ 非貪婪匹配,遇到第一個 </li> 即停止

Match mc = Regex.Match(html, pattern);
if (mc.Success)
{
    string city = mc.Groups["key"].Value; // "北京市 網通"
    Console.WriteLine(city);
}

RegexOptions 實用旗標

var regex = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline);
// IgnoreCase: 大小寫不敏感
// Singleline: 讓 . 能匹配換行符,跨行擷取時必備
// Multiline: 讓 ^ $ 匹配每行開頭結尾
// Compiled: 編譯成 IL,首次較慢但重複使用極快 (靜態 Regex 推薦)
// ExplicitCapture: 僅捕獲命名群組,忽略未命名括號,提升效能

效能與最佳實務

  1. 靜態唯讀 Regex:高頻呼叫請宣告 private static readonly Regex _regex = new Regex(pattern, RegexOptions.Compiled);
  2. 避免災難性回溯:慎用巢狀量詞 (a+)+,改用非貪婪或原子群組 (?>...)
  3. 預先編譯模式:.NET 7+ 支援 [GeneratedRegex] 原始碼產生器,編譯期即完成編譯
  4. HTML 解析首選解析器:Regex 適合「固定格式、小範圍」擷取;完整 DOM 處理請用 AngleSharp/HtmlAgilityPack

常用命名群組速查表

(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})  // 日期解析
(?<ip>(?:\d{1,3}\.){3}\d{1,3})                 // IPv4
(?<email>[\w.+-]+@[\w-]+\.[\w.-]+)             // Email 簡易版
(?<id>[A-Z]\d{9})                              // 台灣身分證字號

掌握命名群組 + 非貪婪匹配 + 適當旗標三大要訣,即能撰寫出既精準又好維護的正則表達式,大幅降低字串解析的 Bug 率與維護成本。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved