2010-06-24 13 views
5

Scrivo un traduttore, non come un progetto serio, solo per divertimento e per diventare un po 'più familiare con le espressioni regolari. Dal codice qui sotto penso che tu possa capire dove sto andando con questo (cheezburger chiunque?).Determinare quale modello corrisponde con Regex.Matches

Sto utilizzando un dizionario che utilizza un elenco di espressioni regolari come le chiavi e il valore del dizionario è un List<string> che contiene un ulteriore elenco di valori di sostituzione. Se ho intenzione di farlo in questo modo, per capire qual è il sostituto, ho ovviamente bisogno di sapere qual è la chiave, come posso capire quale schema ha scatenato la partita?

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

È quello che sto tentando possibile, o c'è un modo migliore per raggiungere questa follia?

+3

'(?! Ues) tion' questo non ha senso, poiché è lo stesso di' tion'. Forse vuoi un look negativo? '(? polygenelubricants

+0

... e Buddha, non Buddah ... e cos'è un gatto soffitto? –

+0

@Tim: Penso che sia un riferimento alla campagna di marketing virale che aveva un gatto che oscillava da un ventilatore a soffitto. –

risposta

6

È possibile assegnare un nome a ogni gruppo di acquisizione in un'espressione regolare e quindi eseguire una query sul valore di ciascun gruppo denominato nella corrispondenza. Questo dovrebbe consentire di fare ciò che vuoi.

Ad esempio, utilizzando l'espressione regolare di seguito,

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

è quindi possibile estrarre il gruppo corrisponde dal risultato della partita:

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

Grazie, questo è esattamente quello che mi serviva! – Andrew

+0

@Andrew: felice di aiutare. –

0

Utilizzando gruppi denominati come Jeff dice che è il modo più robusto .

È anche possibile accedere ai gruppi per numero, poiché sono espressi nel modello.

(first)|(second) 

si può accedere con

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

Naturalmente se si dispone di più parentesi che non si desidera includere, utilizzare l'operatore non cattura:?

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

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

È hai un altro problema 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); 

uscita:

My weite is slite.

String.Replace è un'operazione globale, quindi, anche se weight non corrisponde la regex, vengono cambiate in ogni caso quando slight è trovato. Devi fare la partita, cercare e sostituire allo stesso tempo; Regex.Replace(String, MatchEvaluator) ti permetterà di farlo.

Problemi correlati