2010-12-13 8 views
7

Przełamywałem z metodą python re modules .search. cur to dane wejściowe z widżetu wpisu Tkinter. Ilekroć wpisuję "\" w widżet wpisu, zgłasza ten błąd. Nie jestem pewien, co to za błąd i jak sobie z nim poradzić. Każdy wgląd byłby bardzo doceniany.Python re "fikcyjny błąd ucieczki"

bież jest ciągiem

ys [0] jest ciągiem znaków

Fragment:

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

błąd:

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) 

Odpowiedz

12

"Błędna ucieczka (koniec linii)" oznacza, że ​​twój wzór kończy się odwrotnym ukośnikiem. To nie ma nic wspólnego z Tkinter. Możesz łatwo zduplikować błąd w powłoce interaktywnej:

>>> 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) 

Rozwiązanie? Upewnij się, że wzór nie kończy się pojedynczym odwróconym ukośnikiem.

+0

Czy można traktować \ jak zwykłą postać? Podobnie do metody r "string". – rectangletangle

+2

@ Anteater7171: ukośnik odwrotny jest szczególny dla wyrażeń regularnych. Masz dwie możliwości: nie używaj wyrażeń regularnych lub modyfikuj ciąg znaków, aby usunąć specjalne znaczenie. W przypadku tego ostatniego, dodanie dodatkowego ukośnika odwrotnego powoduje lewę (tzn. Wzorzec "\" oznacza dosłowny ukośnik odwrotny). –

+0

+1 Powinieneś był dodać swój ostatni komentarz do odpowiedzi. Aby rozwinąć komentarz, w kontekście np. re.search, co oznaczałoby zrobienie '' pattern = "foobar \\\\" ", to znaczy potrzebujesz 4 backslashes, więc argument pattern dla re.search kończy się na dwóch, co spowodowałoby prawne wyrażenie regularne. – ThomasH

3

Pierwszy parametr być ponownie wzorzec do wyszukania, a więc jeśli "cur" zawiera ukośnik odwrotny na końcu linii, będzie to nieprawidłowa sekwencja ucieczki. Pewnie zamienili swoje argumenty wokół (nie wiem co tup [0] jest, ale jest to twój wzór?) I powinno być jak ten

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

Jak bardzo rzadko korzystają z danych wprowadzanych przez użytkownika jako wzorzec (chyba że robisz mechanizm wyszukiwania wyrażenia regularnego, w takim przypadku możesz zamiast tego wyświetlić błąd).

HTH.

EDIT:
Błąd to donosi, że używasz znak ucieczki przed końcem linii (co jest co bogus escape (end of line) znaczy), to jest twój wzór kończy się odwrotnym ukośnikiem, które nie jest prawidłowy wzór. Po znaku Escape (ukośnik odwrotny) musi następować inny znak, który usuwa lub dodaje specjalne znaczenie do tego znaku (nie wiesz dokładnie, jak robi to Python, posix tworzy grupy przez dodanie ucieczki do nawiasów, perl usuwa efekt grupy przez jego ucieczkę). To jest \* dopasowuje literalną gwiazdkę, podczas gdy * dopasowuje poprzedni znak 0 lub więcej razy.

+0

Używam danych wprowadzanych przez użytkownika do wyszukiwania zawartości tup [0]. cur jest moim wzorem. – rectangletangle

+1

@Anteater; więc jeśli cur jest wzorem, tzn. użytkownik wchodzi do wzorca, to oczywiście jest on niepoprawny i użytkownik musi być o tym poinformowany ..? – falstro

+0

zależy od tego, czy użytkownik myśli, że wprowadza wyrażenie regularne. Jeśli uważają, że wprowadzają stały ciąg, kod musi zostać naprawiony. Jeśli uważają, że wpisują wyrażenie regularne, powinni zostać poinformowani, że wyrażenie jest nieważne (ale mam nadzieję, że w duchu informowania lub nauczania zamiast karania). –

3

Jeśli próbujesz szukać "cur" w "TUP [0]" należy to zrobić poprzez "try: ... z wyjątkiem ..." blok złapać nieprawidłowy wzór:

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

Rozwiązaniem tego problemu jest użycie nieprzetworzonego ciągu znaków jako tekstu zastępczego.Poniższa nie zadziała:

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

To wygeneruje błąd: fałszywe ucieczkę (koniec linii)

Ale dodaje będzie działać dobrze:

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

Teraz pytanie w jaki sposób można przekonwertować ciąg znaków wygenerowany podczas wykonywania programu do nieprzetworzonego łańcucha znaków w języku Python. Możesz znaleźć rozwiązanie dla tego here. Ale wolę stosując prostsze metody, aby to zrobić:

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

Powyższa metoda może konwertować tylko ASCII i Unicode ciągi w surowych strun. Cóż, działało to dla mnie znakomicie do tej pory :)