沿着以下方向的東西?
string[,] patterns = {
{ "one-1", "cat" },
{ "two-2", "dog" },
{ "three-3", "mouse" },
{ "four-4", "fish" },
};
var regex = buildRegex(patterns);
string[] tests = { "foo", "dog", "bar", "fish" };
foreach (var t in tests) {
var m = regex.Match(t);
Console.WriteLine("{0}: {1}", t, reportMatch(regex, m));
}
輸出
foo: no match
dog: two-2 = dog
bar: no match
fish: four-4 = fish
首先我們逃離組名,並將它們與圖案結合建立一個Regex
實例。任何非單詞字符都將替換爲序列_nnn_
,其中nnn是其UTF-32值。
private static Regex buildRegex(string[,] inputs)
{
string regex = "";
for (int i = 0; i <= inputs.GetUpperBound(0); i++) {
var part = String.Format(
"(?<{0}>{1})",
Regex.Replace(inputs[i,0], @"([\W_])", new MatchEvaluator(escape)),
inputs[i,1]);
regex += (regex.Length != 0 ? "|" : "") + part;
}
return new Regex(regex);
}
private static string escape(Match m)
{
return "_" + Char.ConvertToUtf32(m.Groups[1].Value, 0) + "_";
}
對於比賽的.NET庫並沒有給我們一個簡單的方法來得到一個組的名稱,所以我們必須走另外一條路:每個組的名稱,我們檢查組是否匹配,如果所以不要使用它的名字,並讓調用者知道名字和捕獲的子字符串。
private static string reportMatch(Regex regex, Match m)
{
if (!m.Success)
return "no match";
foreach (var name in regex.GetGroupNames()) {
if (name != "0" && m.Groups[name].Value.Length > 0)
return String.Format(
"{0} = {1}",
Regex.Replace(name, @"_(\d+)_",
new MatchEvaluator(unescape)),
m.Groups[name].Value);
}
return null;
}
private static string unescape(Match m)
{
return Char.ConvertFromUtf32(int.Parse(m.Groups[1].Value));
}
你可能想看看另一種獲取組名的方法:http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.getgroupnames.aspx – 2010-02-02 20:50:12
@Ahmad謝謝!更新。 – 2010-02-02 21:18:05
我去了這個變化。謝謝 – Irwin 2010-02-09 13:20:46