2011-11-19 14 views
6

Quiero tener una expresión regular que encuentre los textos que están "envueltos" entre "HEAD o HEADa" y "HEAD. Es decir, puedo tener un texto que comience con el primero palabra como cabeza o Heada y los siguientes "cabezas" son del tipo de cabeza.Python regex con look behind y alternativas

  1. HEAD\n\n text...text...HEAD \n\n text....text HEAD\n\n text....text .....
  2. HEADa\n\n text...text...HEAD \n\n text....text HEAD\n\n text....text .....

quiero sólo para capturar el texto que se encuentran entre las "cabezas" por lo tanto, tener una expresión regular con mirar hacia atrás y mirar ahea d expresiones buscando mis "cabezas". Tengo la siguiente expresión regular:

var = "HEADa", "HEAD" 

my_pat = re.compile(r"(?<=^\b"+var[0]+r"|"+var[1]+r"\b) \w*\s\s(.*?)(?=\b"+var[1] +r"\b)",re.DOTALL|re.MULTILINE) 

Sin embargo, cuando trato de ejecutar esta expresión regular, estoy recibiendo un mensaje de error que indica que no puedo tener una longitud variable en la mirada detrás de expresión. ¿Qué pasa con esta expresión regular?

+0

Gracias Chris Morgan, mucho más fácil de leer de hecho – user963386

+0

Por cierto, usted debe aceptar las respuestas a sus otras preguntas también. – FailedDev

Respuesta

14

En la actualidad, la primera parte de su expresión regular se parece a esto:

(?<=^\bHEADa|HEAD\b) 

tiene dos alternativas; uno combina cinco caracteres y el otro coincide con cuatro, y es por eso que obtiene el error. Algunos sabores de expresiones regulares le permitirán hacer eso a pesar de que dicen que no permiten búsquedas de longitud variable, pero no Python. Usted podría dividirla en dos lookbehinds, así:

(?:(?<=^HEADa\b)|(?<=\bHEAD\b)) 

... pero es probable que no necesita lookbehinds para esto de todos modos. Tal vez puedas probar:

(?:^HEADa|\bHEAD)\b 

lo que consigue la igualada por (.*?) más adelante seguirá estando disponible a través del grupo # 1. Si realmente necesita todo el texto entre los delimitadores, puede capturar que en el grupo # 1, y ese otro grupo se convertirá en # 2 (o puede usar grupos con nombre, y no tener que hacer un seguimiento de los números) .

En general, mirar hacia atrás nunca debe ser su primer recurso. Puede parecer la herramienta obvia para el trabajo, pero normalmente es mejor que haga una combinación directa y extraiga la pieza que desea con un grupo de captura. Y eso es cierto para todos los sabores, no solo para Python; sólo porque puede hacer más con lookbehinds en otros sabores no significa que debería.

Por cierto, habrás notado que redistribuyo los límites de tus palabras; Creo que esto es lo que realmente pretendiste.

+0

Me tienes al punto :) +1. Además, puedes interpolar tu variable así: ** regex = re.compile ('(? <=^\ B% s |% s \ b) \ w * \ s \ s (. *?) (? = \ b% s \ b) '% (var [0], var [1], var [1]), re.DOTALL | re.MULTILINE) ** – FailedDev

+0

Gracias Allan Moore por la muy buena explicación – user963386