55 votes

Expression rationnelle Python correspondant aux propriétés Unicode

Perl et certains autres moteurs de regex actuels prennent en charge les propriétés Unicode, telles que la catégorie, dans une regex. Par exemple, en Perl, vous pouvez utiliser \p{Ll} pour faire correspondre une lettre minuscule arbitraire, ou p{Zs} pour tout séparateur d'espace. Je ne vois pas de support pour cela dans les lignes 2.x ni 3.x de Python (avec les regrets dus). Est-ce que quelqu'un est au courant d'une bonne stratégie pour obtenir un effet similaire? Les solutions maison sont les bienvenues.

58voto

ronnix Points 717

Le module regex (une alternative au module standard re ) prend en charge les propriétés de points de code Unicode avec la syntaxe \p{} .

23voto

joeforker Points 14483

Avez-vous essayé Ponyguruma , une liaison Python au moteur d’expression régulière Oniguruma ? Dans ce moteur, vous pouvez simplement dire que \p{Armenian} correspond aux caractères arméniens. \p{Ll} ou \p{Zs} travaillent aussi.

6voto

zellyn Points 658

Vous pouvez utiliser avec précaution unicodedata sur chaque personnage:

 import unicodedata

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

5voto

mgibsonbr Points 12998

En parlant de solutions endogènes, il y a quelques temps, j'ai écrit un petit programme pour le faire convertir en unicode catégorie de l'écrit en tant que \p{...} dans une plage de valeurs, extrait de l'unicode spécification (v. 5.0.0). Seules catégories sont pris en charge (ex.: L, Zs), et est limitée à la BMP. Je poste ici au cas où quelqu'un la trouver utile (bien que Oniguruma semble vraiment une meilleure option).

Exemple d'utilisation:

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

Voici la source. Il y a aussi une version JavaScript, en utilisant les mêmes données.

4voto

Jonathan Feinberg Points 24791

Vous avez raison, la propriété Unicode classes ne sont pas pris en charge par le Python regex analyseur.

Si vous souhaitez faire une belle hack, qui pourraient être généralement utile, vous pouvez créer un préprocesseur qui analyse une chaîne de caractères pour la catégorie des jetons (\p{M} ou autre) et les remplace par le caractère correspondant à des ensembles, de sorte que, par exemple, \p{M} deviendrait [\u0300–\u036F\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F], et \P{M} deviendrait [^\u0300–\u036F\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F].

Les gens pourraient vous remercier. :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X