El método de coincidencia Regex no funciona correctamente

Tengo un método que simplemente verifica un archivo de texto en busca de varias cadenas, aunque algunas cadenas no se seleccionan como una coincidencia a pesar de que están presentes en el documento de texto. He incluido la cadena ofensiva que no se encuentra en este ejemplo:

static void Main(string[] args)
{
    string str = @"1009 10.32.0.28 03/05/2012 09:11:48 The license expires in 1192 day(s).";
        StreamReader sr = new StreamReader(@"event_history.txt");
        string allRead = sr.ReadToEnd();
        sr.Close();
        string regMatch = str;
        if (Regex.IsMatch(allRead, regMatch))
        {
            Console.WriteLine("found\n");
        }
        else
        {
            Console.WriteLine("not found\n");
        }

        Console.ReadKey();

}

historial_de_eventos.txt

1009 10.32.0.28 03/05/2012 09:11:48 The license expires in 1192 day(s).

Si reemplazo la coincidencia de expresiones regulares con decir "prueba" y luego agrego "prueba" al archivo de texto, lo detecta como una coincidencia sin problema: S

preguntado el 03 de mayo de 12 a las 15:05

Está utilizando Regex de manera incorrecta. ¿Por qué no usar string.Contains? -

Gran parte de esa puntuación debe escaparse si se usa REGEX. Si sabe exactamente lo que está buscando, contáctenos Contiene () como ie. dicho. De lo contrario, consulte msdn.microsoft.com/en-us/library/az24scfc.aspx para algunas explicaciones -

Es posible que desee aprender primero las expresiones regulares, antes de usarlas. Son todo un lenguaje disfrazado para hacer tu vida un poco más divertida. Si te gustan las nociones masoquistas de diversión, eso es;) -

4 Respuestas

La str no es la expresión regular correcta para lo que está tratando de lograr. por ejemplo el . significa cualquier carácter y el paréntesis alrededor s son una agrupación y no serán capturados. En realidad, solo necesita verificar si allRead contiene str si esa es la cadena que siempre desea verificar (1009, 1192 días, dirección IP y fecha siempre estáticas).

string str = @"1009 10.32.0.28 03/05/2012 09:11:48 The license expires in 1192 day(s).";
StreamReader sr = new StreamReader(@"event_history.txt");
string allRead = sr.ReadToEnd();

if(allRead.Contains(str))
{
    Console.WriteLine("found\n");
}
else
{
    Console.WriteLine("not found\n");
}

Si está buscando una expresión regular que capture valores no estáticos, aquí tiene

string str = @"\d+ \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} \d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2} The license expires in \d+ day\(s\)\.";

contestado el 03 de mayo de 12 a las 16:05

Bueno, es una expresión regular válida, pero no hace lo que quiere el OP. - svick

regMatch=str y str no es una expresión regular. ¿Por qué estás usando RegEx? Deberías estar usando algo similar a

".*The license expires in [0-9]* day(s).".

Yendo más allá, para todas las entradas de IP 10.23.0.28:

"1009 10\.32\.0\.28 ..\/..\/.... ..\:..\:.. The license expires in [0-9]* day(s)."

Usando el archivo regex.txt por ejemplo:

$ cat regex.txt
1009 10.32.0.28 03/05/2012 09:11:48 The license expires in 1192 day(s).
1009 10.32.0.28 04/05/2012 09:11:48 The license expires in 1192 day(s).
1009 10.32.0.29 04/05/2012 09:11:48 The license expires in 1192 day(s).
1009 10.32.0.30 04/05/2012 09:11:48 The license expires in 1192 day(s).

Los resultados son:

$ grep "1009 10\.32\.0\.28 ..\/..\/.... ..\:..\:.. The license expires in [0-9]* day(s)." regex.txt
1009 10.32.0.28 03/05/2012 09:11:48 The license expires in 1192 day(s).
1009 10.32.0.28 04/05/2012 09:11:48 The license expires in 1192 day(s).

si esa es la cadena que siempre desea verificar (1009, 1192 días, dirección IP y fecha siempre estáticas).

Uso:

".... 10\.32\.0\.28 04\/05\/2012 ..\:..\:.. The license expires in 1192 day(s)."

contestado el 03 de mayo de 12 a las 16:05

Esto es bastante codicioso, ignora el otro texto que publicó el OP, no le importa si no hay números presentes y no escapa del paréntesis o el último .. - Joe

Sí, debe agregar expresiones regulares adicionales para señalar las entradas exactas. Sin duda, puede llevar esto más lejos eliminando el comodín en el prefijo. - jason huntley

Estas usando Regex.IsMatch as String.Contains. Las expresiones regulares tienen su propia sintaxis, por lo que no funcionarán (en general).

En su ejemplo particular, necesita escapar de los paréntesis alrededor s, porque el motor de expresiones regulares no los comparará tal como están escritos ahora, son el operador de captura. Los puntos también deben escaparse, aunque, irónicamente, los puntos de expresión regular coinciden con los puntos. Entonces:

string str = @"1009 10\.32\.0\.28 03/05/2012 09:11:48 The license expires in 1192 day\(s\)\.";

contestado el 03 de mayo de 12 a las 15:05

Creo que sería más fácil mantener la cadena como está y usar Regex.Escape(). - svick

La razón por la que la expresión regular no coincide es porque ( y ) son caracteres especiales en una expresión regular. Representan una agrupación, un valor al que desea hacer referencia más adelante. Para cambiarlos a caracteres normales, agregue un \ justo delante de ellos. Entonces su expresión regular debería verse como

@"1009 10.32.0.28 03/05/2012 09:11:48 The license expires in 1192 day\(s\)."

contestado el 03 de mayo de 12 a las 15:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.