2008-08-07 18 views
15

Escribo un tipo de cliente Telnet en C# y parte de lo que tengo que analizar son las secuencias de escape ANSI/VT100, específicamente, solo aquellas usadas para el color y el formato (detallado here).¿Por qué es más rápida esta expresión regular?

Un método que tengo es uno encontrar todos los códigos y eliminarlos, así que puede hacer que el texto sin formato, si es necesario:

 
public static string StripStringFormating(string formattedString) 
{ 
    if (rTest.IsMatch(formattedString)) 
     return rTest.Replace(formattedString, string.Empty); 
    else 
     return formattedString; 
} 

Soy nuevo a las expresiones regulares y se sugirió que se use esto:

static Regex rText = new Regex(@"\e\[[\d;]+m", RegexOptions.Compiled);

Sin embargo, esto falló si el código de escape estaba incompleto debido a un error en el servidor. De manera que esto fue sugerido, pero mi amigo advirtió que podría ser más lenta (éste también coincide con otra condición (z) que podría venir a través de más adelante):

static Regex rTest = 
       new Regex(@"(\e(\[([\d;]*[mz]?))?)?", RegexOptions.Compiled);

Esto no sólo trabajado, pero era de hecho más rápido a y redujo el impacto en mi representación de texto. ¿Puede alguien explicarle a un novato de expresiones regulares, por qué? :)

Respuesta

1

Sin hacer un análisis detallado, supongo que es más rápido debido a los signos de interrogación. Éstos permiten que la expresión regular sea "floja" y se detiene tan pronto como tienen suficiente para coincidir, en lugar de verificar si el resto de la entrada coincide.

No estoy del todo contento con esta respuesta, porque esto se aplica principalmente a los signos de interrogación después de * o +. Si estuviera más familiarizado con la entrada, podría tener más sentido para mí.

(También, para el formateo de código, puede seleccionar todo el código y pulse Ctrl + K que tienen que añadir los cuatro espacios requeridos.)

3

La razón por la # 1 es más lenta es que [\ d;] + es un cuantificador codicioso. ¿Usando +? o *? va a hacer una cuantificación perezosa. Vea MSDN - Quantifiers para más información.

Es posible que desee probar:

"(\e\[(\d{1,2};)*?[mz]?)?" 

que puede ser más rápido para usted.

3

¿Realmente quieres ejecutar la expresión regular dos veces? Sin haber comprobado (mal yo) me habría pensado que esto funcionaría así:

public static string StripStringFormating(string formattedString) 
{  
    return rTest.Replace(formattedString, string.Empty); 
} 

Si lo hace, debería ver correr el doble de rápido ~ ...

+0

Pensando en ello ahora, eso no tiene sentido, se ejecuta una expresión regular en una línea sin ninguna identidad es lo mismo que ejecutar una comprobación primero ver si coincide en absoluto. ¡Obtienes el mismo resultado! – Nidonocu

1

No estoy seguro de si esto ayudará con lo que está trabajando, pero hace mucho tiempo escribí una expresión regular para analizar los archivos gráficos ANSI.

(?s)(?:\e\[(?:(\d+);?)*([A-Za-z])(.*?))(?=\e\[|\z) 

Devolverá cada código y el texto asociado a él.

Cadena de entrada:

<ESC>[1;32mThis is bright green.<ESC>[0m This is the default color. 

Resultados:

[ [1, 32], m, This is bright green.] 
[0, m, This is the default color.] 
+0

Gracias por esta respuesta, tendré a mano esta expresión cuando sin duda regrese y revise el código más adelante para posibles mejoras. :) Como he descubierto, las expresiones regulares 'más grandes' tienden a ser más rápidas que las más pequeñas. – Nidonocu

+0

También estoy interesado en todo lo que esté haciendo con los códigos ANSI en .NET. Actualmente estoy rehaciendo mi sitio en rieles en lugar de .NET, pero siempre tengo curiosidad por ver cómo las personas pueden aprovechar .NET para interpretar ANSI. – lordscarlet

Cuestiones relacionadas