pensé que por defecto mi Regex exhibiría el comportamiento codicioso que quiero, pero no lo es en el siguiente código:expresiones regulares se comporta perezoso, debe ser codicioso
Regex keywords = new Regex(@"in|int|into|internal|interface");
var targets = keywords.ToString().Split('|');
foreach (string t in targets)
{
Match match = keywords.Match(t);
Console.WriteLine("Matched {0,-9} with {1}", t, match.Value);
}
Salida:
Matched in with in
Matched int with in
Matched into with in
Matched internal with in
Matched interface with in
Ahora se dan cuenta de que podía conseguir que funcione para este pequeño ejemplo si simplemente solucionaron las palabras clave por longitud descendente, pero
- quiero entender por qué esto no está funcionando como se esperaba, y
- el proyecto actual que estoy trabajando en tiene muchas más palabras en la expresión regular y es importante mantenerlos en orden alfabético.
Así que mi pregunta es: ¿Por qué esto es perezoso y cómo lo soluciono?
No estoy seguro de si su uso real es más complicado, pero si el ejemplo anterior es en realidad lo que está haciendo, creo que sería mil veces mejor ir por su lista de palabras buscando coincidencias con el método IndexOf . Si la expresión regular simplemente contiene un montón de palabras en una alternancia, es probable que el rendimiento sea una mierda. – Josh
@Josh - No, el ejemplo está simplificado. La aplicación real está leyendo archivos de idioma para generar lexers y analizadores gramaticales. Estoy un poco oxidado en mi regex; mi problema parece tan obvio ahora! – Stomp
@Josh: los motores Regex pueden hacer muchas optimizaciones para tales casos, incluyendo descartar muchos controles después de no poder hacer coincidir un prefijo común. Por ejemplo, si el primer carácter no es "i", ninguna de las ramas que comiencen con "i" se verificará. No estoy seguro si el motor de .NET hace esto, pero me sorprendería si no lo hiciera. –