Domanda

Perl e alcuni altri motori regex attuali supportano le proprietà Unicode, ad esempio la categoria, in una regex. Per esempio. in Perl è possibile utilizzare \p{Ll} per abbinare una lettera minuscola arbitraria, o per qualsiasi p{Zs} separati da uno spazio. Non vedo il supporto per questo sia nel 2.x né 3.x linee di Python (con rimpianti dovuti). C'è qualcuno a conoscenza di una buona strategia per ottenere un effetto simile? Le soluzioni homegrown sono i benvenuti.

È stato utile?

Soluzione

Hai provato Ponyguruma , un pitone vincolante per il Oniguruma motore delle espressioni regolari? In quel motore si può semplicemente dire \p{Armenian} per abbinare caratteri armeni. \p{Ll} o \p{Zs} lavoro troppo.

Altri suggerimenti

È possibile utilizzare faticosamente unicodedata su ogni personaggio:

import unicodedata

def strip_accents(x):
    return u''.join(c for c in unicodedata.normalize('NFD', x) if unicodedata.category(c) != 'Mn')

A proposito di soluzioni homegrown, qualche tempo fa ho scritto un piccolo programma di fare proprio questo - convertire una categoria unicode scritto come \p{...} in un intervallo di valori, estratto dalle href="http://unicode.org/versions/Unicode5.0.0/" unicode (v.5.0.0). Solo le categorie sono supportati (es .: L, Zs), che si trovano in BMP. Sto postando qui in caso qualcuno trovare utile (anche se questo Oniguruma sembra davvero una scelta migliore).

Esempio di utilizzo:

>>> from unicode_hack import regex
>>> pattern = regex(r'^\\p{Lu}(\\p{L}|\\p{N}|_)*')
>>> print pattern.match(u'疂_1+2').group(0)
疂_1
>>>

Ecco il fonte . C'è anche una versione JavaScript , utilizzando gli stessi dati.

Hai ragione che le classi di proprietà Unicode non sono supportati dal parser regex di Python.

Se si voleva fare un bel hack, che sarebbe generalmente utili, è possibile creare un preprocessore che analizza una stringa per tali gettoni di classe (\p{M} o altro) e li sostituisce con i set di caratteri corrispondenti, in modo che, ad esempio, , \p{M} diventerebbe [\u0300–\u036F\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F], e \P{M} diventerebbe [^\u0300–\u036F\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F].

La gente grazie. :)

Si noti che mentre \p{Ll} non ha equivalenti in Python espressioni regolari, \p{Zs} dovrebbe essere coperto da '(?u)\s'. Il (?u), come i documenti dicono, “Make \ w, \ W, \ b, \ B, \ d, \ D, \ s e \ S dipendano dal database delle proprietà dei caratteri Unicode.” E \s qualsiasi carattere di spaziatura.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top