2010-06-24 20 views
5

Ich schreibe einen Übersetzer, nicht als seriöses Projekt, nur zum Spaß und um mit regulären Ausdrücken vertrauter zu werden. Aus dem unten stehenden Code könnt ihr herausfinden, wo ich damit hingehe (Cheezburger irgendjemand?).Ermitteln, welches Muster mit Regex.Matches übereinstimmt

Ich verwende ein Wörterbuch, das eine Liste von regulären Ausdrücken als Schlüssel verwendet, und der Wörterbuchwert ist List<string>, der eine weitere Liste von Ersatzwerten enthält. Wenn ich es so mache, um herauszufinden, was der Ersatz ist, muss ich natürlich wissen, was der Schlüssel ist, wie kann ich herausfinden, welches Muster das Spiel ausgelöst hat?

 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); 
     } 

Ist was ich versuche, oder gibt es einen besseren Weg, um diesen Wahnsinn zu erreichen?

+3

'(?! Ues)" Dies macht keinen Sinn, denn das ist genauso wie 'tion'. Vielleicht möchten Sie negative Lookbehind? "(?)?" Auch "Gottheit", nicht "Gesinnung". – polygenelubricants

+0

... und Buddha, nicht Buddah ... und was ist eine Deckenkatze? –

+0

@Tim: Ich denke, es ist ein Hinweis auf die virale Marketing-Kampagne, die eine Katze von einem Deckenventilator schwingen ließ. –

Antwort

6

Sie können jede Erfassungsgruppe in einem regulären Ausdruck benennen und dann den Wert jeder benannten Gruppe in Ihrer Übereinstimmung abfragen. Dies sollte Ihnen erlauben zu tun, was Sie wollen.

Zum Beispiel den regulären Ausdruck unten, mit

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

Sie können dann extrahieren die Gruppe aus Ihrem Spiel Ergebnis passt:

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

Danke, das ist genau das, was ich brauchte! – Andrew

+0

@Andrew: Glücklich zu helfen. –

0

benannten Gruppen verwenden wie Jeff sagt, ist die robusteste Art und Weise .

Sie können auch auf die Gruppen nach Nummer zugreifen, wie sie in Ihrem Muster angegeben sind.

(first)|(second) 

mit

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

Natürlich zugegriffen werden, wenn Sie mehr Klammern, die Sie möchten, dass das Nicht-Capture-Operator nicht enthalten, verwenden:

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

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

Sie habe ein anderes Problem. Check this out:

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); 

Ausgang:

My weite is slite.

String.Replace ist ein globaler Betrieb, so dass, obwohl weight nicht die Regex paßt, wird es geändert sowieso, wenn slight gefunden wird. Sie müssen die Übereinstimmung, Suche und Ersetzung gleichzeitig durchführen. Regex.Replace(String, MatchEvaluator) lässt Sie das tun.

Verwandte Themen