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 = "身分證 ***-*******, ***-*******"
Regex.IsMatch(input, pattern) 會快取最近 15 個靜態模式 (預設),但**強烈建議**將模式封裝為 static readonly Regex 物件並加 RegexOptions.Compiled,避免重複解析、啟用 JIT 編譯提升 30%+ 效能。regex.IsMatch(input) 無快取機制,必須自行管理物件生命週期。(a+)+, (a*)*。(?>a+) (需 .NET 7+ / PCRE 相容模式) 或改寫邏輯。Regex.MatchTimeout (建構子參數或 AppDomain 設定) 防止惡意輸入掛死執行緒。// 避免雙重跳脫,提升可讀性
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 |
善用 static readonly Regex + Compiled + MatchTimeout 三重保護,正則表達式將成為你處理文本的利器而非隱患。