2014-09-26 8 views
7

Ho qualche codice python scritto in una versione precedente di python (2.x) e faccio fatica a farlo funzionare. Sto usando python 3,4python versione 3.4 non supporta un prefisso "ur"

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

(che è parte di un tokenizer)

+0

Volevate farlo funzionare su * entrambi Python 2 e 3 *? O solo su Python 3? –

+0

Grazie per la rapida risposta! Ho solo bisogno che funzioni su python 3. –

risposta

9

http://bugs.python.org/issue15096

Titolo: Drop supporto per il "ur" prefix stringa
Quando PEP 414 supporto per letterali Unicode espliciti restaurata in Python 3, il "ur" prefisso della stringa è stato considerato un sinonimo per il prefisso "r".

, utilizzare 'r' invece di 'ur'

+0

Tuttavia non è un sinonimo in Python 2.7. –

+0

Che non è rilevante per l'OP, stanno cercando di farlo funzionare in 3.4. La mia lettura è che se volessero 3.4 e 2.7 lo direbbero. – KevinDTimm

+0

È stato rimosso perché non è stato possibile riprodurre il comportamento dei valori letterali stringa raw di Python 2 'ur '...' '. –

8

Infatti, Python 3.4 supporta solo u'...' (per sostenere il codice che deve funzionare sia su Python 2 e 3) e r'....', ma non entrambi. Questo perché la semantica di come funziona ur'..' in Python 2 è diversa da come funziona ur'..' in Python 3 (in Python 2, gli escape ancora vengono elaborati, in Python 3 una stringa `r '...' non lo farebbe).

Si noti che nel questo caso specifico non c'è differenza tra il valore letterale stringa stringa e il valore normale! Si può semplicemente utilizzare:

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

e funzionerà sia in Python 2 e 3.

Per i casi in cui una stringa letterale grezzo ha importanza, si potrebbe decodificare la stringa prima da raw_unicode_escape su Python 2, di prendere il AttributeError su 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 

Se si sta scrivendo codice Python 3 solo(in modo che non ha bisogno di essere eseguito su Python 2 più), Basta inserire i u tutto:

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

Ti ho upvoted per l'idea di codifica 'raw_unicode_string', ma il tuo codice produrrà risultati diversi tra Python 2 e Python 3. – itsadok

+0

@itsadok: è abbastanza vicino per questi scopi. Si potrebbe anche usare una stringa regolare, double backslash di escape e decodificare come 'unicode_escape':' _eng_word = '[a-zA-Z] [a-zA-Z0-9'.] * '; _eng_word.replace (r '\\', r '\\\\'). decode ('unicode_escape') ', questo è l'approccio che' six' usa. –

+1

@itsadok: e prendi in considerazione che i modelli '\ uhhhh' hanno significato anche in' re' * *. Quindi, anche se in Python 3, si finisce con sequenze Unicode '\\ uhhhh' (escape), hanno ancora lo stesso significato nell'espressione regolare come se si fosse passati nel punto di accesso Unicode letterale. –

1

Si riporta un confronto (alcuni dei) diversi stringa prefissi letterali in Python 2 (0,7) e 3 (.4+): enter image description here

Come potete vedere, in Python 3 non c'è modo di avere un letterale che non elabori gli escape, ma elabora i letterali unicode. Per ottenere un tale stringa con il codice che funziona sia in Python 2 e 3, l'uso:

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

In realtà, il tuo esempio non è molto buona, dal momento che non ha nessun letterali Unicode, o sequenze di escape. Un esempio migliore sarebbe:

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

in Python 2:

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

In Python 3:

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

Che è in realtà la stessa cosa.

Problemi correlati