首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> C# 入門

C# 正則表達式速查手冊:常用驗證模式、分組捕獲、替換、性能優化、RegexOptions 詳解

     編輯:C# 入門

正則表達式是文本處理的瑞士軍刀。本文匯總**高頻驗證模式**、**核心語法詳解**、**C# Regex 進階用法 (命名分組、替換委托、預編譯、Span 支持)**、以及**性能優化陷阱**,作為開發隨查手冊。

一、高頻驗證模式庫 (可直接複製)

場景正則模式說明
純數字^\d+$ / ^[0-9]+$至少一位
固定長度數字 (n 位)^\d{n}$如 ^\d{6}$ 驗證 6 位郵編
範圍長度數字 (m-n 位)^\d{m,n}$
非零開頭整數^[1-9]\d*$
正浮點數 (2 位小數)^\d+(\.\d{1,2})?$金額驗證常用
Email^[\w-\.]+@([\w-]+\.)+[\w-]{2,}$簡易版,嚴格 RFC 5322 極其複雜
手機號 (中國大陸)^1[3-9]\d{9}$包含虛擬運營商段
身份證號 (18 位)^\d{17}[\dXx]$僅格式,校驗碼需算法驗證
URL (HTTP/HTTPS)^https?://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
IPv4 地址^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$
中文字符^[\u4e00-\u9fa5]+$基本區塊
中文+字母+數字+下劃線^[\u4e00-\u9fa5a-zA-Z0-9_]+$用戶名常用
日期 (yyyy-MM-dd)^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$格式校驗,邏輯有效性需代碼判斷
密碼 (8-16位,含大小寫數字特殊)^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,16}$零寬斷言
去除 HTML 標簽<[^>]*>替換為空串
提取 URL 域名https?://([^/]+)分組 1 為域名

二、核心語法速查

符號含義示例匹配
.任意單字符 (除換行符,加 Singleline 含換行)a.c → "abc", "a-c"
\d數字 [0-9]
\w單詞字符 [a-zA-Z0-9_]
\s空白字符 (空格、制表、換行)
\D \W \S非數字、非單詞、非空白
^字符串開始 (多行模式下行首)
$字符串結束 (多行模式下行尾)
*零次或多次 {0,}
+一次或多次 {1,}
?零次或一次 {0,1}
{n}恰好 n 次
{n,}至少 n 次
{n,m}n 到 m 次
? (量詞後)**非貪婪/懶惰匹配** (匹配最少).*? 最少字符
()**捕獲組** (編號 1,2...)(\d{4})-(\d{2})
(?:)**非捕獲組** (不佔用編號,分組用)(?:\d{3}-){2}
(?<name>)**命名捕獲組** (C# 推薦用)(?<year>\d{4})
(?=)**正向預查** (零寬斷言,不消耗字符)\d(?=\d) 後面有數字的數字
(?!)**負向預查**\d(?!\\d) 後面非數字的數字
(?<=)**正向後顧** (.NET 支持變長)(?<=\d)\d 前面有數字的數字
(?**負向後顧**
|或cat|dog
[]字符集[aeiou]
[^]排除字符集[^0-9]
\b單詞邊界
\k<name>反向引用命名組(?<q>['""]).*?\k<q>

三、C# Regex 進階實戰模式

1. 命名分組 + 強類型提取 (推薦)


string pattern = @"^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$";
string input = "2023-10-01";

var match = Regex.Match(input, pattern);
if (match.Success)
{
    int year = int.Parse(match.Groups["year"].Value);
    int month = int.Parse(match.Groups["month"].Value);
    int day = int.Parse(match.Groups["day"].Value);
    // match.Groups["year"] 等同 match.Groups[1],但可讀性強、重構安全
}

2. 替換委托:動態計算替換值


// 將所有數字乘以 2
string input = "價格: 10, 20, 30";
string result = Regex.Replace(input, @"\d+", m => (int.Parse(m.Value) * 2).ToString());
// 結果: "價格: 20, 40, 60"

// 複雜邏輯:根據上下文決定替換
result = Regex.Replace(input, @"(?<prefix>\$)(?<amount>\d+)", m => 
    $"{m.Groups["prefix"].Value}{decimal.Parse(m.Groups["amount"].Value) * 1.1m:F2}");

3. 分割保留分隔符


// 保留標點符號分割句子
string text = "你好!世界。真好?";
var parts = Regex.Split(text, @"(?<=[。!?])"); 
// 結果: ["你好!", "世界。", "真好?", ""]

4. 多行模式處理日志/代碼


string log = @"2023-10-01 10:00:01 INFO  啟動
2023-10-01 10:00:02 ERROR 連接失敗
2023-10-01 10:00:03 WARN  重試";

// ^ 和 $ 匹配行首行尾
var errors = Regex.Matches(log, @"^.*ERROR.*$", RegexOptions.Multiline);
// 單行模式:. 匹配換行
var block = Regex.Match(log, @"ERROR.*?WARN", RegexOptions.Singleline);

5. .NET 7+ Span/ReadOnlySpan 支持 (零分配)


// Regex.IsMatch / Match / Count / EnumerateMatches 支持 ReadOnlySpan
ReadOnlySpan span = "abc123def".AsSpan();
bool hasDigit = Regex.IsMatch(span, @"\d"); // true, 無字符串分配

// 枚舉匹配 (高性能,無 Match 對象分配)
foreach (var match in Regex.EnumerateMatches(span, @"\d+"))
{
    // match 是 ValueMatch 結構體,包含 Index, Length
    var numSpan = span.Slice(match.Index, match.Length);
    int num = int.Parse(numSpan); // .NET 7+ 支持 Span 解析
}

四、RegexOptions 詳解

選項效果常用場景
IgnoreCase忽略大小寫關鍵字搜索、HTML 標簽匹配
Multiline^/$ 匹配行首尾多行文本逐行處理
Singleline. 匹配換行符跨行匹配 HTML/代碼塊
ExplicitCapture僅捕獲命名組 (?<name>),普通 () 變非捕獲大型正則優化、避免無意捕獲
Compiled編譯為 IL,**啟動慢、匹配快****高頻複用的靜態正則** (靜態 readonly 字段)
IgnorePatternWhitespace忽略模式中的空白,允許註釋 #編寫可讀性強的複雜正則
RightToLeft從右向左匹配特定解析場景
ECMAScript兼容 JS 正則行為前後端共用正則
CultureInvariant忽略文化差異 (如土耳其語 I/ı)全球化應用

五、性能優化鐵律

  1. 靜態預編譯:高頻正則定義為 `static readonly Regex _regex = new Regex(pattern, RegexOptions.Compiled);` 避免重複編譯。
  2. 避免災難性回溯:嵌套量詞 (a+)+、互斥選項重疊 (a|a*)+。使用**原子組** (?>...) 或**佔有優先量詞** ++ *+ ?+ (需 .NET 支持) 防回溯。
  3. 錨點優先:模式開頭加 ^ 或 \b,失敗快。
  4. 具體化字符集:用 [a-f0-9] 代替 . 或 \w。
  5. 複用 Match/Enumerator:大文本用 EnumerateMatches (Span) 或 Match.NextMatch(),避免 Matches() 一次性分配集合。
  6. 緩存實例:`Regex` 實例**線程安全**,可全局靜態緩存。

六、常用工具方法封裝


public static class RegexHelper
{
    // 預編譯常用正則
    private static readonly Regex _emailRegex = new Regex(
        @"^[\w-\.]+@([\w-]+\.)+[\w-]{2,}$", 
        RegexOptions.Compiled | RegexOptions.IgnoreCase);

    private static readonly Regex _mobileRegex = new Regex(
        @"^1[3-9]\d{9}$", 
        RegexOptions.Compiled);

    public static bool IsEmail(string s) => !string.IsNullOrEmpty(s) && _emailRegex.IsMatch(s);
    public static bool IsMobile(string s) => !string.IsNullOrEmpty(s) && _mobileRegex.IsMatch(s);

    // 通用提取首個匹配分組值
    public static string Extract(string input, string pattern, string groupName = "value")
    {
        var m = Regex.Match(input, pattern);
        return m.Success ? m.Groups[groupName].Value : null;
    }

    // 高亮關鍵字 (HTML)
    public static string Highlight(string html, string keyword, string cssClass = "highlight")
    {
        if (string.IsNullOrEmpty(keyword)) return html;
        string escaped = Regex.Escape(keyword);
        return Regex.Replace(html, $"({escaped})", $"$1", RegexOptions.IgnoreCase);
    }
}

總結

正則表達式威力巨大,但**可讀性差、易出災難性回溯、調試困難**。原則:**能用字符串方法 (`Contains`、`StartsWith`、`Split`、`IndexOf`、`Span` 切片) 解決的,絕不寫正則**;必須用時:**命名分組、靜態預編譯、詳盡註釋、單元測試覆蓋邊界**。推薦工具:regex101.com (實時調試、解釋、代碼生成)、RegexStorm (.NET 專用測試)。

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