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

C# 正則表達式實戰大全:常見驗證模式與最佳實踐

     編輯:關於C語言

命名空間與核心類別

using System.Text.RegularExpressions; // Regex, Match, MatchCollection, Group

驗證工具類別完整實作

public static class RegexValidator
{
    // 編譯選項:Compiled 提升重複使用效能,IgnoreCase 不區分大小寫
    private static readonly RegexOptions _opt = RegexOptions.Compiled | RegexOptions.IgnoreCase;

    // ========== 數字類 ==========
    /// 正整數 (1, 2, ...)
    public static bool IsNaturalNumber(string input) =>
        Regex.IsMatch(input, @"^[1-9]\d*$", _opt);

    /// 非負整數 (0, 1, 2, ...)
    public static bool IsWholeNumber(string input) =>
        Regex.IsMatch(input, @"^\d+$", _opt);

    /// 整數 (含負數)
    public static bool IsInteger(string input) =>
        Regex.IsMatch(input, @"^-?\d+$", _opt);

    /// 正數 (整數/小數,含 0.5, 1.23)
    public static bool IsPositiveNumber(string input) =>
        Regex.IsMatch(input, @"^(?:\d+\.?\d*|\.\d+)$", _opt) && !input.Contains("..");

    /// 數字 (整數/小數,含正負)
    public static bool IsNumber(string input) =>
        Regex.IsMatch(input, @"^-?(?:\d+\.?\d*|\.\d+)$", _opt) && !input.Contains("..") && !input.Contains("--");

    // ========== 字元類 ==========
    /// 純英文字母
    public static bool IsAlpha(string input) =>
        Regex.IsMatch(input, @"^[A-Za-z]+$", _opt);

    /// 英數字混合
    public static bool IsAlphaNumeric(string input) =>
        Regex.IsMatch(input, @"^[A-Za-z0-9]+$", _opt);

    /// 中文字元 (含常用標點)
    public static bool IsChinese(string input) =>
        Regex.IsMatch(input, @"^[\u4e00-\u9fa5,。!?、;:「」『』()《》〈〉【】]+$");

    // ========== 格式類 ==========
    /// Email (RFC 5322 簡化版)
    public static bool IsEmail(string input) =>
        Regex.IsMatch(input, @"^[^@\s]+@[^@\s]+\.[^@\s]+$", _opt);

    /// 手機號碼 (台灣)
    public static bool IsTaiwanMobile(string input) =>
        Regex.IsMatch(input, @"^09\d{8}$");

    /// 身分證字號 (台灣)
    public static bool IsTaiwanId(string input) =>
        Regex.IsMatch(input, @"^[A-Z][12]\d{8}$", _opt);

    /// IPv4 位址
    public static bool IsIpv4(string input) =>
        Regex.IsMatch(input, @"^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$");

    /// URL (http/https)
    public static bool IsUrl(string input) =>
        Regex.IsMatch(input, @"^https?://[^\s/$.?#].[^\s]*$", _opt);

    /// 日期 yyyy-MM-dd
    public static bool IsDateYmd(string input) =>
        Regex.IsMatch(input, @"^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$") &&
        DateTime.TryParse(input, out _); // 進一步驗證 2/30 等非法日期

    // ========== 進階:提取與替換 ==========
    /// 提取所有符合模式的子字串
    public static string[] ExtractAll(string input, string pattern)
    {
        var matches = Regex.Matches(input, pattern, _opt);
        var arr = new string[matches.Count];
        for (int i = 0; i < matches.Count; i++) arr[i] = matches[i].Value;
        return arr;
    }

    /// 替換第一個匹配
    public static string ReplaceFirst(string input, string pattern, string replacement) =>
        Regex.Replace(input, pattern, replacement, _opt, TimeSpan.FromSeconds(1), 1);

    /// 替換所有匹配
    public static string ReplaceAll(string input, string pattern, string replacement) =>
        Regex.Replace(input, pattern, replacement, _opt, TimeSpan.FromSeconds(1));
}

使用範例

string[] tests = { "123", "-45", "3.14", "abc", "abc123", "test@email.com", "0912345678" };

foreach (var t in tests)
{
    Console.WriteLine($"{t,15} | Nat:{RegexValidator.IsNaturalNumber(t)} | Int:{RegexValidator.IsInteger(t)} | Num:{RegexValidator.IsNumber(t)} | Alpha:{RegexValidator.IsAlpha(t)} | AlNum:{RegexValidator.IsAlphaNumeric(t)} | Email:{RegexValidator.IsEmail(t)} | Mobile:{RegexValidator.IsTaiwanMobile(t)}");
}

// 提取範例
string text = "訂單 A-1001, B-2002, C-3003 已出貨";
var orders = RegexValidator.ExtractAll(text, @"[A-Z]-\d{4}");
// orders = ["A-1001", "B-2002", "C-3003"]

// 替換範例
string masked = RegexValidator.ReplaceAll("身分證 A123456789, B234567890", @"[A-Z][12]\d{8}", "***-*******");
// masked = "身分證 ***-*******, ***-*******"

效能與安全關鍵點

1. 靜態編譯快取

  • Regex.IsMatch(input, pattern) 會快取最近 15 個靜態模式 (預設),但**強烈建議**將模式封裝為 static readonly Regex 物件並加 RegexOptions.Compiled,避免重複解析、啟用 JIT 編譯提升 30%+ 效能。
  • 實例方法 regex.IsMatch(input) 無快取機制,必須自行管理物件生命週期。

2. 災難性回溯防禦

  • 避免巢狀量詞:(a+)+, (a*)*。
  • 使用**佔有優先量詞** (Possessive) 或**原子分組**:(?>a+) (需 .NET 7+ / PCRE 相容模式) 或改寫邏輯。
  • 設定 Regex.MatchTimeout (建構子參數或 AppDomain 設定) 防止惡意輸入掛死執行緒。

3. 原生字串字面值 (C# 11+)

// 避免雙重跳脫,提升可讀性
private static readonly Regex EmailRegex = new(
    @"^[^@\s]+@[^@\s]+\.[^@\s]+$",
    RegexOptions.Compiled | RegexOptions.IgnoreCase,
    TimeSpan.FromMilliseconds(100) // 超時保護
);

常用正則語法速查

語法說明範例匹配
\d數字 [0-9]\d{3} → 123
\w英數字底線 [A-Za-z0-9_]\w+ → user_name
\s空白字元 (空格、Tab、換行)
.任意單字元 (除換行)
^ $字串開頭/結尾 (多行模式下為行首/行尾)
* + ?0或多 / 1或多 / 0或1
{n,m}n 到 m 次\d{4,6}
[abc]字元集合
[^abc]排除字元集合
(abc)捕獲群組
(?:abc)非捕獲群組 (僅分組,不佔用 $1)
|或cat|dog

線上測試工具推薦

  • Regex101 (支援 .NET Flavor、即時解釋、效能分析)
  • RegExr (視覺化、社群範例庫)

善用 static readonly Regex + Compiled + MatchTimeout 三重保護,正則表達式將成為你處理文本的利器而非隱患。

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