2010-06-24 13 views
5

Escribo un traductor, no como un proyecto serio, solo por diversión y para familiarizarme un poco más con las expresiones regulares. Desde el código a continuación, creo que puedes averiguar hacia dónde voy con esto (¿quién es Cheezburger?).Determinar qué patrón coincide con el uso de Regex.Matches

Estoy usando un diccionario que usa una lista de expresiones regulares como las claves y el valor del diccionario es List<string> que contiene una lista adicional de valores de reemplazo. Si voy a hacerlo de esta manera, para poder averiguar cuál es el sustituto, obviamente necesito saber cuál es la clave, ¿cómo puedo averiguar qué patrón desencadenó la coincidencia?

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

¿Es lo que estoy intentando posible, o hay una mejor manera de lograr esta locura?

+3

'(?! Ues) tion' esto no tiene sentido, ya que es lo mismo que' tion'. ¿Quizás quieres un look negativo detrás? '(? polygenelubricants

+0

... y Buda, no Buddah ... ¿y qué es un gato de techo? –

+0

@Tim: Creo que es una referencia a la campaña de marketing viral que tenía un gato colgando de un ventilador de techo. –

Respuesta

6

Puede nombrar cada grupo de captura en una expresión regular y luego consultar el valor de cada grupo con nombre en su coincidencia. Esto debería permitirle hacer lo que quiere.

Por ejemplo, el uso de la expresión regular a continuación,

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

a continuación, puede extraer los partidos de grupo de su resultado del partido:

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

¡Gracias, esto es exactamente lo que necesitaba! – Andrew

+0

@Andrew: contento de ayudar. –

0

El uso de grupos nombrados como Jeff dice es la forma más robusta .

También puede acceder a los grupos por número, ya que están expresados ​​en su patrón.

(first)|(second) 

se puede acceder con

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

Por supuesto, si usted tiene más paréntesis, que no desea incluir, utilice el operador no captura:?

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

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

Usted Tengo otro problema. Mira esto:

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

de salida:

My weite is slite.

String.Replace es una operación global, por lo que aunque weight no coincide con la expresión regular, que de todos modos se cambia cuando se encuentra slight. Debe hacer la coincidencia, buscar y reemplazar al mismo tiempo; Regex.Replace(String, MatchEvaluator) le permitirá hacer eso.

Cuestiones relacionadas