2011-11-18 20 views
5

Estoy tratando de aprender más sobre regex hoy.Regex: ¿cómo usar lookahead/lookbehind en el resultado de un patrón?

Estoy tratando de hacer coincidir un número de orden que no esté entre corchetes (#1234 pero no [#1234]) pero mi pregunta es más general sobre el uso de aserciones de búsqueda anticipada en un patrón arbitrario.

En mis primeros intentos noté que mi coincidencia de búsqueda negativa \d+(?!\]) provocaría que el \d+ mantuviera los dígitos correspondientes hasta que no fuera seguido por un ]. Necesito que los dígitos coincidan solo si a su totalidad no le sigue ].

Mi solución actual elimina la coincidencia en el primer dígito mirando hacia adelante para ver si hay ] en la cadena de dígitos.

¿Es ésta una forma estándar de hacerlo? Solo estoy repitiendo el patrón de coincidencia en la búsqueda anticipada. Si esta fuera una expresión regular más compleja, ¿lo abordaría de la misma manera? Repite la coincidencia válida seguida de la coincidencia no válida y haz que el motor de expresiones regulares se repita para cada letra.

Para las coincidencias válidas, debería coincidir tantas veces como los personajes de la coincidencia.

(?<!\[) # not preceded by [ 
#\d+ 
(?!\d*\]) # not followed zero+ digits and ] 

# or (?!\d|\]) # not followed by digit or ] 

¡Agradecería cualquier comentario!

+0

No está seguro de lo que entendemos por" ... sólo si su totalidad no es seguida por un ]". ¿Puede agregar un ejemplo de una cadena que no está obteniendo la correspondencia que desea y cuál debería ser la coincidencia en ese caso? – Faust

+0

@Faust: estoy obteniendo la combinación que deseo, solo creo que mi método no es bueno. Narendra Yadala señaló lo que necesitaba exactamente para evitar el retroceso. Gracias a todos –

Respuesta

8

Puede lograr lo que desea mediante el uso de un cuantificador posesivo junto con lookarounds como esto

(?<!\[)#\d++(?!\]) 

El problema en su caso es cuando se utiliza \d+ Permite dar marcha atrás y termina teniendo una coincidencia parcial #123. Una vez que lo cambie a un cuantificador posesivo, no retrocederá y solo coincidirá si la secuencia de dígitos no está precedida/seguida por corchetes.

Live Demo

Editar Si cuantificadores posesivos no son compatibles entonces usted puede utilizar éste

#\d(?<!\[#\d)(?!\d*\])\d* 
+0

Brilliant! 'A diferencia de un cuantificador codicioso, no abandonará las coincidencias cuando el motor retroceda. Con un cuantificador posesivo, el trato es todo o nada. 'Eso es exactamente lo que necesitaba. Me alegro de haber hecho la pregunta:) Lo aceptaré tan pronto como pueda. –

+0

Ouch, acaba de descubrir que python re no lo admite ... Probablemente usará mi función original, entonces :( –

+0

@YujiTomita Se agregó una expresión regular que funcionará cuando los cuantificadores posesivos no sean compatibles. –

Cuestiones relacionadas