2009-07-08 65 views
5

正則表達式:命名組和替換

Regex.Replace(string source, string pattern, string replacement) 

最後的參數支持模式的替代品,如${groupName}和其他的方法(但我不知道在運行時的組名)。

在我來說,我有一個動態創建的模式:

(?<c0>word1)|(?<c1>word2)|(?<c2>word3) 

我的目的是根據組名的值來代替每個組。例如,單詞「word1」將被替換爲<span class="c0">word1</span>。這是搜索結果突出顯示像谷歌。

是否有可能使用上面的方法不使用重載方法MatchEvaluator參數?

在此先感謝!

+0

我只是去與MatchEvaluator ...它的工作原理... – 2009-07-09 07:18:37

+0

是的,謝謝!其實我有MatchEvaluator的工作解決方案。但如何優雅將是一個解決方案只有一行代碼而不是六七:) – Alex 2009-07-09 09:49:17

回答

3

我不認爲以你所建議的方式使用$ {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.