2010-12-13 4 views
7

He estado jugando con los módulos de python re .search método. cur es la entrada de un widget de entrada Tkinter. Cada vez que ingreso una "\" en el widget de entrada, arroja este error. No estoy seguro de cuál es el error o cómo lidiar con él. Cualquier idea sería muy apreciada.Python re "error de escape falso"

cur es una cadena

TUP [0] es también una cadena

Fragmento:

se = re.search(cur, tup[0], flags=re.IGNORECASE) 

El error:

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "C:\Python26\Lib\Tkinter.py", line 1410, in __call__ 
    return self.func(*args) 
    File "C:\Python26\Suite\quidgets7.py", line 2874, in quick_links_results 
    self.quick_links_results_s() 
    File "C:\Python26\Suite\quidgets7.py", line 2893, in quick_links_results_s 
    se = re.search(cur, tup[0], flags=re.IGNORECASE) 
    File "C:\Python26\Lib\re.py", line 142, in search 
    return _compile(pattern, flags).search(string) 
    File "C:\Python26\Lib\re.py", line 245, in _compile 
    raise error, v # invalid expression 
error: bogus escape (end of line) 

Respuesta

12

"escape falso (fin de línea)" significa que su patrón termina con una barra diagonal inversa. Esto no tiene nada que ver con Tkinter. Puede duplicar el error con bastante facilidad en un shell interactivo:

>>> import re 
>>> pattern="foobar\\" 
>>> re.search(pattern, "foobar") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/re.py", line 142, in search 
    return _compile(pattern, flags).search(string) 
    File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/re.py", line 241, in _compile 
    raise error, v # invalid expression 
sre_constants.error: bogus escape (end of line) 

¿La solución? Asegúrate de que tu patrón no termine con una sola barra invertida.

+0

¿Es posible tratar a \ como un personaje ordinario? Similar al método r "cadena". – rectangletangle

+2

@ Anteater7171: la barra diagonal inversa es especial para las expresiones regulares. Tiene dos opciones: no usar expresiones regulares o modificar la cadena para eliminar el significado especial. Para este último, agregar una barra invertida adicional es el truco (es decir: el patrón '\\' significa una barra invertida literal). –

+0

+1 Deberías haber agregado tu último comentario a la respuesta. Para ampliar el comentario, en el contexto de, por ejemplo, re.search que significaría hacer '' pattern = "foobar \\\\" '', es decir, necesitas 4 barras diagonales inversas para que el argumento de patrón para re.search termine teniendo dos, lo que haría una expresión regular legal. – ThomasH

3

El primer parámetro re es el patrón a buscar, por lo tanto si 'cur' contiene una barra invertida al final de la línea, será una secuencia de escape no válida. Es probable que haya intercambiado sus argumentos en torno (no sé lo que TUP [0] es, pero ¿es su patrón?) Y debe ser así

se = re.search(tup[0], cur, flags=re.IGNORECASE) 

A medida que muy raramente utiliza la entrada del usuario como una patrón (a menos que esté haciendo un mecanismo de búsqueda de expresiones regulares, en cuyo caso es posible que desee mostrar el error en su lugar).

HTH.

EDITAR:
El error se informa es que usted está utilizando un carácter de escape antes del final de la línea (que es lo bogus escape (end of line) medios), que es su forma finaliza con una barra invertida, lo cual no es una patrón válido El carácter de escape (barra invertida) debe ir seguido de otro carácter, que elimina o agrega un significado especial a ese carácter (no está seguro exactamente cómo lo hace, posix crea grupos al agregar escape entre paréntesis, perl elimina el efecto de grupo escapándolo). Es decir, \* coincide con un asterisco literal, mientras que * coincide con el carácter anterior 0 o más veces.

+0

Estoy usando la entrada del usuario para buscar los contenidos de tup [0]. cur es mi patrón. – rectangletangle

+1

@Anteater; Bueno, entonces, si cur es el patrón, es decir, el usuario está ingresando el patrón, obviamente es incorrecto y el usuario necesita estar al tanto. – falstro

+0

que depende de si el usuario piensa que está ingresando una expresión regular. Si creen que están ingresando una cadena fija, el código necesita ser reparado. Si creen que están ingresando una expresión regular, se les debe informar que la expresión no es válida (pero, con suerte, en el espíritu de informar o enseñar en lugar de castigar). –

3

Si usted está tratando de buscar "cur" en "TUP [0]" Usted debe hacer esto a través de "tratar: ... excepto: ..." bloque de atrapar patrón no válido:

try : 
    se = re.search(cur, tup[0], flags=re.IGNORECASE) 
except re.error, e: 
    # print to stdout or any status widget in your gui 
    print "Your search pattern is not valid." 
    # Some details for error: 
    print e 
    # Or some other code for default action. 
12

La solución a este problema es utilizar una cadena sin formato como texto de reemplazo.El siguiente no funcionará:

re.sub('this', 'This \\', 'this is a text') 

arrojará el error: escapar falsa (fin de línea)

Pero la siguiente funcionará bien:

re.sub('this', r'This \\', 'this is a text') 

Ahora, la pregunta es cómo se convierte una cadena generada durante el tiempo de ejecución del programa en una cadena sin formato en Python. Puede encontrar una solución para este here. Pero yo prefiero usar un método más simple de hacer esto:

def raw_string(s): 
    if isinstance(s, str): 
     s = s.encode('string-escape') 
    elif isinstance(s, unicode): 
     s = s.encode('unicode-escape') 
    return s 

El método anterior se puede convertir sólo cadenas de caracteres ASCII y Unicode en cadenas primas. Bueno, esto ha estado funcionando bien para mí hasta la fecha :)