我不認爲以你所建議的方式使用$ {groupname}是可行的,除非我誤解了正在執行的確切替換。原因是替換字符串必須以這樣一種方式構建,即佔用每個組名稱。由於它們是動態生成的,因此不能實現。換句話說,在一個聲明中,如何設計一個替換字符串來覆蓋c0 ... cn並替換它們各自的捕獲值?您可以遍歷名稱,但是如何保持修改後的文本完整,以每個組名稱執行1次替換?
雖然我確實有一個可能的解決方案。它仍然使用MatchEvaluator重載,但對於一些lambda表達式和LINQ,您可以將其降至1行。不過,爲了清晰起見,我會對其進行格式化。也許這將符合你的需求,或者指向你正確的方向。
string text = @"The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.";
string[] searchKeywords = { "quick", "fox", "lazy" };
// build pattern based on keywords - you probably had a routine in place for this
var patternQuery = searchKeywords
.Select((s, i) =>
String.Format("(?<c{0}>{1})", i, s) +
(i < searchKeywords.Length - 1 ? "|" : ""))
.Distinct();
string pattern = String.Join("", patternQuery.ToArray());
Console.WriteLine("Dynamic pattern: {0}\n", pattern);
// use RegexOptions.IgnoreCase for case-insensitve search
Regex rx = new Regex(pattern);
// Notes:
// - Skip(1): used to ignore first groupname of 0 (entire match)
// - The idea is to use the groupname and its corresponding match. The Where
// clause matches the pair up correctly based on the current match value
// and returns the appropriate groupname
string result = rx.Replace(text, m => String.Format(@"<span class=""{0}"">{1}</span>",
rx.GetGroupNames()
.Skip(1)
.Where(g => m.Value == m.Groups[rx.GroupNumberFromName(g)].Value)
.Single(),
m.Value));
Console.WriteLine("Original Text: {0}\n", text);
Console.WriteLine("Result: {0}", result);
輸出:
Dynamic pattern: (?<c0>quick)|(?<c1>fox)|(?<c2>lazy)
Original Text: The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
Result: The <span class="c0">quick</span> brown <span class="c1">fox</span> jumps over the <span class="c2">lazy</span> dog. The <span class="c0">quick</span> brown <span class="c1">fox</span> jumps over the <span class="c2">lazy</span> dog.
我只是去與MatchEvaluator ...它的工作原理... – 2009-07-09 07:18:37
是的,謝謝!其實我有MatchEvaluator的工作解決方案。但如何優雅將是一個解決方案只有一行代碼而不是六七:) – Alex 2009-07-09 09:49:17