2010-06-24 58 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)会让你这样做。