2014-09-26 13 views
7

Mam trochę kodu Pythona zapisanego w starszej wersji Pythona (2.x) i staram się, aby to działało. Używam Pythona 3.4python w wersji 3.4 nie obsługuje prefiksu "ur"

_eng_word = ur"[a-zA-Z][a-zA-Z0-9'.]*" 

(to jest częścią tokenizera)

+0

Czy chcesz, aby to działało * zarówno w Pythonie 2, jak i 3 *? Lub tylko w Pythonie 3? –

+0

Dzięki za szybką reakcję! Potrzebuję go tylko do pracy z pythonem 3. –

Odpowiedz

9

http://bugs.python.org/issue15096

Tytuł: Spadek poparcia dla "ur" string prefiksu
Kiedy PEP 414 przywrócono wsparcie dla wyraźnych literałów Unicode w Pythonie 3, "ur" prefiksu ciąg został uznany za synonim przedrostka "r".

Więc, użyj 'r' zamiast 'Ur'

+0

Jednak nie jest to synonim w Pythonie 2.7. –

+0

Co nie jest związane z PO, próbują sprawić, by działało w wersji 3.4. Moim zdaniem jest tak, że gdyby chcieli 3.4 i 2.7, powiedzieliby tak. – KevinDTimm

+0

Został on usunięty, ponieważ nie można odtworzyć zachowania liter "surowych ciągów" Pythona 2 'ur '...'. –

8

Rzeczywiście, Python 3.4 obsługuje tylko u'...' (wspieranie kod, który trzeba uruchomić zarówno Python 2 i 3) oraz r'....', ale nie oba. To dlatego, że semantyka działania ur'..' w Pythonie 2 różni się od tego, jak działałby ur'..' w Pythonie 3 (w Pythonie 2, \uhhhh i \Uhhhhhhhh nadal przetwarzane są ucieczki, w Pythonie 3 łańcuch `r '...' nie byłby).

Należy zauważyć, że w przypadku ten konkretny przypadek nie ma różnicy między surowym literałem ciągłym a zwykłym! można po prostu użyć:

_eng_word = u"[a-zA-Z][a-zA-Z0-9'.]*" 

i będzie działać zarówno w Pythonie 2 i 3.

W przypadkach, gdzie surowy ciąg dosłowne ma znaczenia, można dekodowania surowy sznurek od raw_unicode_escape na Pythonie 2, łapanie AttributeError na Python 3:

_eng_word = r"[a-zA-Z][a-zA-Z0-9'.]*" 
try: 
    # Python 2 
    _eng_word = _eng_word.decode('raw_unicode_escape') 
except AttributeError: 
    # Python 3 
    pass 

Jeśli pisania kodu tylkoPython 3 (więc nie trzeba uruchamiać na Python już 2) tylko kropla u całkowicie:

_eng_word = r"[a-zA-Z][a-zA-Z0-9'.]*" 
+0

Przegłosowałem dla ciebie pomysł kodowania 'raw_unicode_string', ale twój kod będzie generował różne wyniki pomiędzy Python 2 i Python 3. – itsadok

+0

@itsadok: jest wystarczająco blisko do tych celów. Możesz również użyć zwykłego ciągu znaków, podwójnie uciekanych ukośników odwrotnych, a następnie dekodować jako 'unicode_escape':' _eng_word = '[a-zA-Z] [a-zA-Z0-9'.] * '; _eng_word.replace (r '\\', r '\\\\'). decode ('unicode_escape') ', jest to podejście, które używa' sześć'. –

+1

@itsadok: i weź pod uwagę, że '\ uhhhh' wzorce mają znaczenie w' re' * too *. Więc nawet jeśli w Pythonie 3 skończysz z sekwencjami unikodowymi "\\ uhhhh" (ucieczkowe), nadal mają one takie samo znaczenie w wyrażeniu regularnym, jakbyś przeszedł w dosłownym codepoint Unicode. –

1

Ta tabela porównuje (niektóre) różne przedrostki Łańcuch znaków w Pythonie 2 (.7) i 3 (.4+): enter image description here

Jak widać, w Pythonie 3 nie ma sposobu na literał, który nie przetwarza ucieczek, ale przetwarza literały Unicode. Aby uzyskać taki ciąg znaków z kodem, który działa zarówno w Pythonie 2 i 3, przeznaczenie:

br"[a-zA-Z][a-zA-Z0-9'.]*".decode('raw_unicode_escape') 

Właściwie Twój przykład nie jest bardzo dobra, ponieważ nie ma żadnych literałów Unicode, lub sekwencje. Lepszym przykładem będzie:

br"[\u03b1-\u03c9\u0391-\u03a9][\t'.]*".decode('raw_unicode_escape') 

W python 2:

>>> br"[\u03b1-\u03c9\u0391-\u03a9][\t'.]*".decode('raw_unicode_escape') 
u"[\u03b1-\u03c9\u0391-\u03a9][\\t'.]*" 

W Pythonie 3:

>>> br"[\u03b1-\u03c9\u0391-\u03a9][\t'.]*".decode('raw_unicode_escape') 
"[α-ωΑ-Ω][\\t'.]*" 

który jest naprawdę to samo.

Powiązane problemy