Compartir a través de


Preguntas más frecuentes sobre System.Text.RegularExpressions

Preguntas más frecuentes sobre el espacio de nombres System.Text.RegularExpressions.

¿Por qué [insertar regex complicado y largo] no se corresponde con lo que espero?
Regex se bloquea cuando intento buscar coincidencias usando mi expresión. ¿Cuál es la razón?

Nos encanta conocer sus ideas, problemas o peticiones. Quizás esté interesado en saber por qué se ha diseñado algo de una manera en particular, la mejor manera de solucionar un problema o los motivos por los que el código que ha creado no funciona como esperaba. Además, puede enviar al equipo de BCL sus sugerencias para versiones futuras de Framework, como clases adicionales que incluir (siempre es útil describir los escenarios que necesita admitir) o API nuevas para clases existentes.

Para enviar su pregunta, simplemente envíe un correo electrónico a The BCL Team (bclpub@microsoft.com).

 


¿Por qué [insertar regex complicado y largo] no se corresponde con lo que espero?
En general, es muy difícil consultar expresiones complejas y determinar a qué deben corresponder. Lo que hacemos normalmente con estas expresiones es simplemente probarlas para averiguar qué parte no coincide. Por ejemplo, reemplace la segunda mitad de la expresión con .* y observe si encuentra coincidencias.

Si es así, vuelva a escribir algo más de la expresión. De lo contrario, reemplace mayor parte de la expresión con .*. Al final, encontrará el problema. Puede usar la misma técnica al comienzo de la expresión o incluso en subexpresiones internas que se aíslan fácilmente.

También es importante tener en cuenta qué es lo que coincide y no sólo "si coincide". Para ello, usamos el siguiente fragmento de código a fin de extraer todas las coincidencias, grupos y capturas. El resultado puede ser muy largo en el caso de expresiones complejas, pero es muy útil.

[C#]public static void WriteGroups(Regex regex, Match match) {  Console.WriteLine("Success: " + match.Success);  Console.WriteLine("\r\nmatch.Value = \"" + match. Value + "\", Index = " + match.Index + ", Length = " + match.Length);  Console.WriteLine("\r\nmatch.Groups.Count = " + match.Groups.Count);  for ( int i=0; i ‹ match.Groups.Count; i++ ) {    string name = regex.GroupNameFromNumber(i);    Console.WriteLine(" \r\n\tmatch.Groups[" + name + "].Value = \"" + match.Groups[i].Value + "\", Index = " + match.Groups[i].Index + ", Length = " + match.Groups[i].Length);    Console. WriteLine("\tmatch.Groups[" + name + "].Captures.Count = " + match.Groups[i].Captures.Count);    for ( int j=0; j ‹ match.Groups[ name].Captures.Count; j++ ) {      Console.WriteLine("\t\tmatch.Groups[" + name + "].Captures[" + j + "].Value = \"" + match.Groups[i].Captures[j].Value + " \", Index = " + match.Groups[i].Captures[j].Index + ", Length = " + match.Groups[i].Captures[j].Length);    }  }}


Regex se bloquea cuando intento buscar coincidencias usando mi expresión. ¿Cuál es la razón?
Regex no se bloquea realmente. Lo que ocurre es que el proceso lleva mucho tiempo. Es posible escribir expresiones donde el tiempo de ejecución aumente de forma exponencial con la longitud de la cadena de búsqueda. Normalmente, esto se debe a la existencia de algunos cuantificadores anidados. Por ejemplo, el siguiente código muestra una expresión simple con un cuantificador anidado:

 

[VB]
Dim r As Regex = New Regex("(.*)+q")
For i As Integer = 0 to 50
  Dim s As String = New String ('a', i)
  Dim start As DateTime = DateTime. Now
  r.Match(s)
  Dim end As DateTime = DateTime.Now
  Console.WriteLine(end -start)
Next

Este código crea cadenas de longitud creciente que contienen sólo la letra "a". Observe que la expresión regular no coincidirá con estas cadenas, porque es necesario que la cadena termine en una "q". Si ejecuta este fragmento de código, verá que tras algunas iteraciones en cadenas cortas, comienza a tardar mucho tiempo en finalizar cada llamada a r.Match(s). Con cada letra agregada, tarda el doble de tiempo.

La solución es intentar deshacerse completamente de todos los cuantificadores anidados. Normalmente, esto no es un problema, ya que la mayoría de las expresiones se pueden escribir sin ellos. Si sabe de algún caso que no se puede escribir sin usar cuantificadores anidados, nos interesa verlo.