2010-07-14 17 views
7

Jugando con expresiones regulares, especialmente la combinación equilibrada del sabor .NET, llegué a un punto en el que me di cuenta de que no entendía el funcionamiento interno del motor tan bien como pensaba. Agradecería cualquier aporte sobre por qué mis patrones se comportan de la manera en que lo hacen. Pero puño ...¿Cómo funcionan los condicionales en grupos alternativos en .NET regex?

Descargo de responsabilidad: Esta pregunta es puramente teórica, y cualquier resultado obtenido aquí nunca será utilizado, ni modificado ni utilizado en el código de producción para analizar HTML. Nunca. Lo prometo. Temo al pony. =)

Ahora a mi problema. Trataré de hacer coincidir la letra A, si no está precedida por un #. Para demostrar, siempre usaré la cadena ..A..#..A... Aquí, el primer A debe coincidir. Por supuesto, esta es una tarea bastante fácil usando "A(?<!^.*#.*)", pero deseo usar condicionales aquí, ya que se pueden usar para combinaciones equilibradas y otras cosas interesantes.

Lo que intenté es

"A(?<=^(#(?<q>)|[^#])*(?(q)(?!)))" 

La manera en que yo interpreto es: cuando el motor encounteres una "A", que se remonta al inicio de la cadena, y para cada carácter añadir un partido de vacío a el grupo de captura q si el caracter es un #. Entonces debería fallar si q contiene una coincidencia. Lo que no entiendo es por qué esta expresión coincide con As en mi cadena de muestra.

Cuando me basta con quitar la búsqueda hacia atrás y combinar toda la cadena, esto funciona:

"^(#(?<q>)|[^#])*(?(q)(?!))A" 

partidos toda la cadena hasta la primera A, incluso si cuantificador del primer grupo es codicioso. Insertar un '#' al principio también hará que la coincidencia falle (como se desee).

Entonces, ¿cómo se observan los grupos, los grupos de captura nombrados dentro de ellos y los condicionales juegan juntos?

Gracias!

Editar: Este problema se puede ver más fácilmente en (?<=(?<q>)(?(q)(?!)))., que no debe coincidir con ningún carácter, pero coincide con todo.

+0

+1 y sólo pude párrafo segundo hasta el momento./De acuerdo, lea todo el asunto, pero lástima que esto es muy específico de C# y no puedo contribuir ... ¡AÚN! ¡Pregunta favorita y marcada! – polygenelubricants

+0

@polygenelubricants: ¡Jeje, gracias! =) – Jens

Respuesta

3

Las condiciones no son realmente tan útiles en la comparación equilibrada, o en cualquier otro lugar, para el caso. ;) Equilibrado de coincidencia funciona mediante el uso de un grupo de captura con nombre como una pila; cada vez que ese grupo coincide con algo, el texto coincidente se inserta en la pila. También hay una sintaxis especial para hacer estallar la pila. Esto es una buena introducción:

http://blog.stevenlevithan.com/archives/balancing-groups

+0

De hecho, me enfrenté a este problema al tratar de usar la concordancia equilibrada primero. Esta técnica parece fallar cuando se usa en un vistazo detrás, y no tengo idea de por qué. Esta pregunta es el caso más simple donde se puede ver la misma falla. – Jens

Cuestiones relacionadas