2010-06-24 5 views
5

J'écris un traducteur, pas comme un projet sérieux, juste pour m'amuser et pour me familiariser un peu avec les expressions régulières. Du code ci-dessous, je pense que vous pouvez travailler là où je vais avec ça (cheezburger quelqu'un?).Détermination du modèle correspondant à l'aide de Regex.Matches

J'utilise un dictionnaire qui utilise une liste d'expressions régulières comme clés et la valeur du dictionnaire est un List<string> qui contient une liste supplémentaire de valeurs de remplacement. Si je vais le faire de cette façon, afin de déterminer ce qu'est le substitut, j'ai évidemment besoin de savoir quelle est la clé, comment puis-je déterminer quel modèle a déclenché le match?

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

Est ce que j'essaie possible, ou y a-t-il un meilleur moyen d'atteindre cette folie?

+3

'(?! Ues) tion' cela n'a aucun sens, puisque c'est exactement la même chose que 'tion'. Peut-être que vous voulez lookbehind négatif? '(? polygenelubricants

+0

... et Bouddha, pas Buddah ... et qu'est-ce qu'un chat de plafond? –

+0

@Tim: Je pense que c'est une référence à la campagne de marketing viral qui a eu un chat se balançant d'un ventilateur de plafond. –

Répondre

6

Vous pouvez nommer chaque groupe de capture dans une expression régulière, puis interroger la valeur de chaque groupe nommé dans votre correspondance. Cela devrait vous permettre de faire ce que vous voulez.

Par exemple, en utilisant l'expression régulière ci-dessous,

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

vous pouvez extraire les matches de groupe à partir de votre résultat du match:

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

Merci, c'est exactement ce dont j'avais besoin! – Andrew

+0

@Andrew: Heureux d'aider. –

0

En utilisant des groupes nommés comme le dit Jeff est la façon la plus robuste .

Vous pouvez également accéder aux groupes par numéro, tels qu'ils sont exprimés dans votre motif.

(first)|(second) 

peut être consulté avec

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

Bien sûr, si vous avez plus entre parenthèses que vous ne voulez pas inclure, utilisez l'opérateur non-capture:

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

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

Vous J'ai un autre problème. 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); 

sortie:

My weite is slite.

String.Replace est une opération globale, donc même si weight ne correspond pas à l'expression régulière, il se change de toute façon quand slight se trouve. Vous devez faire la correspondance, la recherche et le remplacement en même temps; Regex.Replace(String, MatchEvaluator) vous permettra de faire cela.

Questions connexes