using System.Text.RegularExpressions;
public IEnumerable ExtractNumbers(string input, bool groupConsecutive = true)
{
if (string.IsNullOrEmpty(input)) yield break;
string pattern = groupConsecutive ? @"\d+" : @"\d";
foreach (Match m in Regex.Matches(input, pattern))
{
if (int.TryParse(m.Value, out int num))
yield return num;
}
}
string test = "abc2345 345fdf678 jdhfg945";
// 1. 連續數字群組 (\d+)
foreach (var n in ExtractNumbers(test, true))
Console.WriteLine(n);
// 輸出:
// 2345
// 345
// 678
// 945
// 2. 單一數字 (\d)
foreach (var n in ExtractNumbers(test, false))
Console.WriteLine(n);
// 輸出:
// 2
// 3
// 4
// 5
// 3
// 4
// 5
// 6
// 7
// 8
// 9
// 4
// 5
| 模式 | 名稱 | 匹配行為 |
|---|---|---|
| \d | 單一數字 | 匹配 0-9 任一字元,每個字元獨立匹配 |
| \d+ | 一個或多個數字 | 貪婪匹配連續數字序列,直到遇非數字 |
| \d* | 零或多個數字 | 匹配空字串或連續數字,慎用 (易產生大量空匹配) |
| \d{n} | 固定 n 位數字 | 如 \d{4} 匹配 4 位數字 (年份、編號) |
| \d{n,m} | n 到 m 位數字 | 如 \d{3,6} 匹配 3-6 位數字 |
public IEnumerable ExtractNumericValues(string input)
{
// 可選正負號、整數部、可選小數點與小數部、可選科學標記法
string pattern = @"[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?";
foreach (Match m in Regex.Matches(input, pattern))
{
if (double.TryParse(m.Value, out double val))
yield return val;
}
}
// 測試
string s = "溫度 -12.5°C, 價格 +3,456.78, 科學 1.23E-4";
foreach (var v in ExtractNumericValues(s))
Console.WriteLine(v);
// -12.5
// 3456.78 (注意: 千分位逗號未被模式匹配,實際輸出 3456.78 需先移除逗號)
// 1.23E-4 → 0.000123
static readonly Regex NumRegex = new Regex(@"\d+", RegexOptions.Compiled); 避免重複編譯。Regex.Matches 回傳 MatchCollection 會一次配置所有匹配,記憶體較大;可用 Match.NextMatch() 迭代器模式逐個處理。input.Any(char.IsDigit) 最快。[TestMethod]
public void ExtractNumbers_Test()
{
var result = ExtractNumbers("Order 1234-A5", true).ToList();
CollectionAssert.AreEqual(new[] { 1234, 5 }, result);
result = ExtractNumbers("v1.2.3", false).ToList();
CollectionAssert.AreEqual(new[] { 1, 2, 3 }, result);
}
原文連結:https://www.bianceng.cn/Programming/csharp/201410/45578.htm