2010-06-24 16 views
5

我正在寫一個翻譯器,而不是任何嚴肅的項目,只是爲了好玩並且變得對正則表達式更熟悉一些。從下面的代碼我想你可以找出我要去哪裏(cheezburger任何人?)。確定使用Regex.Matches匹配哪種模式

我使用的字典使用正則表達式列表作爲鍵,字典值是List<string>,其中包含替換值的更多列表。如果我要這樣做,爲了弄清楚替補是什麼,我顯然需要知道關鍵是什麼,我怎樣才能找出哪種模式引發了比賽?

 var dictionary = new Dictionary<string, List<string>> 
     {      
      {"(?!e)ight", new List<string>(){"ite"}}, 
      {"(?!ues)tion", new List<string>(){"shun"}}, 
      {"(?:god|allah|buddah?|diety)", new List<string>(){"ceiling cat"}}, 
      .. 
     } 

     var regex = "(" + String.Join(")|(", dictionary.Keys.ToArray()) + ")"; 

     foreach (Match metamatch in Regex.Matches(input 
      , regex 
      , RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture)) 
     { 
      substitute = GetRandomReplacement(dictionary[ ????? ]); 
      input = input.Replace(metamatch.Value, substitute); 
     } 

是我試圖實現的,還是有更好的方法來實現這種瘋狂?

+3

'(?!ues)tion'這是沒有意義的,因爲這與'tion'一樣。也許你想要負面的後顧之憂? '(?<!UE)的tion'?此外,「神」,而不是「虔誠」。 – polygenelubricants 2010-06-24 16:54:41

+0

......和佛,不是佛......什麼是天花貓? – 2010-06-24 19:23:32

+0

@Tim:我認爲這是對病毒營銷活動的一個參考,它讓一隻貓擺脫了吊扇。 – 2010-06-25 12:44:03

回答

6

您可以在正則表達式中命名每個捕獲組,然後查詢匹配中每個命名組的值。這應該讓你做你想做的事。

例如,使用下面的正則表達式,

(?<Group1>(?!e))ight 

,那麼你可以提取組從比賽的結果一致:

match.Groups["Group1"].Captures 
+1

謝謝,這正是我所需要的! – Andrew 2010-06-24 19:26:07

+0

@Andrew:樂於幫忙。 – 2010-06-25 12:43:21

0

使用命名組像傑夫說是最可靠的方法。

您也可以通過編號訪問羣組,因爲它們在您的模式中表示。

(first)|(second) 

可以

match.Groups[1] // match group 2 -> second 

當然可以訪問,如果你有你不希望包括,使用非捕獲操作更括號:

((?:f|F)irst)|((?:s|S)econd) 

match.Groups[1].Value // also match group 2 -> second 
1

你還有另一個問題。檢查了這一點:

string s = @"My weight is slight."; 
Regex r = new Regex(@"(?<!e)ight\b"); 
foreach (Match m in r.Matches(s)) 
{ 
    s = s.Replace(m.Value, "ite"); 
} 
Console.WriteLine(s); 

輸出:

My weite is slite.

String.Replace是一個全球性的操作,所以儘管weight不匹配正則表達式,當發現slight它得到反正改變。你需要做匹配,查找和替換; Regex.Replace(String, MatchEvaluator)會讓你這樣做。