2011-12-12 15 views
6

Estoy intentando construir una expresión regular que coincida con expresiones regulares entre dos barras diagonales. Mi principal problema es que las expresiones regulares pueden contener barras diagonales, escapadas por una barra invertida. Intento filtrarlos con una aserción negativa de búsqueda hacia atrás (solo coincide con la barra diagonal de cierre si no hay retrocesos en la posición actual), sin embargo, ahora estoy teniendo el problema de que no obtengo la coincidencia, si la propia expresión regular en realidad termina con una barra invertida escapada.Expresión regular: unir cadena entre dos barras si la cadena misma contiene barras oblicuas

programa de pruebas:

#!/usr/bin/python 
import re 
teststrings=[ 
    """/hello world/""", 
    """/string with foreslash here \/ and here\//""", 
    """/this one ends with backlash\\\\/"""] 

patt="""^\/(?P<pattern>.*)(?<!\\\\)\/$""" 

for t in teststrings: 
    m=re.match(patt,t) 
    if m!=None: 
     print t,' => MATCH' 
    else: 
     print t," => NO MATCH" 

de salida:

/hello world/ => MATCH 
/string with foreslash here \/ and here\// => MATCH 
/this one ends with backlash\\/ => NO MATCH 

¿Cómo puedo modificar la afirmación de que sólo se golpeó si hay una sola reacción negativa en la posición actual, pero no dos?

¿O existe una forma mejor de extraer la expresión regular? (Tenga en cuenta, en el archivo real que trato de analizar las líneas contienen algo más que la expresión regular no puedo simplemente buscar la primera y la última barra por línea y obtener todo lo relacionado..)

+0

En el ejemplo del mundo real, ¿podría haber escapado antes/después de la primera/última "real" barras? –

+0

sí, la cadena después de la expresión regular puede tener caracteres arbitrarios, incluidas las barras – Gryphius

Respuesta

16

Prueba esto:

pattern = re.compile(r"^/(?:\\.|[^/\\])*/") 

Explicación:

^  # Start of string 
/  # Match/
(?:  # Match either... 
\\. # an escaped character 
|  # or 
[^/\\] # any character except slash/backslash 
)*  # any number of times. 
/  # Match/

Para su aplicación "mundo real" (la búsqueda de la primera "cadena delimitada por barras", haciendo caso omiso de barras escapado), que haría uso de

pattern = re.compile(r"^(?:\\.|[^/\\])*/((?:\\.|[^/\\])*)/") 

Esto le consigue los siguientes: barras

>>> pattern.match("foo /bar/ baz").group(1) 
'bar' 
>>> pattern.match("foo /bar\/bam/ baz").group(1) 
'bar\\/bam' 
>>> pattern.match("foo /bar/bam/ baz").group(1) 
'bar' 
>>> pattern.match("foo\/oof /bar\/bam/ baz").group(1) 
'bar\\/bam' 
+2

Creo que necesita '\\.' Para hacer coincidir un carácter escapado. – interjay

+0

Vaya. Si gracias. Editará ... –

+0

¡perfecto! ¡muchas gracias! – Gryphius

Cuestiones relacionadas