Expresiones regulares Python que coinciden con las propiedades de Unicode

Perl y algunos otros motores actuales de expresiones regulares admiten propiedades Unicode, como la categoría, en una expresión regular. Por ejemplo, en Perl puede usar \p{Ll} para hacer coincidir una minúscula arbitraria, o p{Zs} para cualquier separador de espacio. No veo soporte para esto en las líneas 2.x ni 3.x de Python (con el debido arrepentimiento). ¿Alguien es consciente de una buena estrategia para obtener un efecto similar? Las soluciones de cosecha propia son bienvenidas.

¿Has probado Ponyguruma , un enlace de Python al motor de expresión regular de Oniguruma ? En ese motor, simplemente puedes decir \p{Armenian} para que coincida con los caracteres armenios. \p{Ll} o \p{Zs} también funcionan.

El módulo regex (una alternativa al módulo re estándar) admite las propiedades de punto de código Unicode con la syntax \p{} .

Puedes usar minuciosamente los datos unicoded en cada personaje:

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

Hablando de soluciones locales, hace un tiempo escribí un pequeño progtwig para hacer precisamente eso: convertir una categoría Unicode escrita como \p{...} en un rango de valores, extraído de la especificación Unicode (v.5.0.0). Solo se admiten categorías (ej .: L , Zs ), y está restringido a BMP. Lo estoy publicando aquí en caso de que alguien lo encuentre útil (aunque Oniguruma realmente parece ser una mejor opción).

Ejemplo de uso:

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

Aquí está la fuente . También hay una versión de JavaScript , utilizando los mismos datos.

Tiene razón en que las clases de propiedades de Unicode no son compatibles con el analizador de expresiones regulares de Python.

Si quisiera hacer un buen pirateo, eso sería generalmente útil, podría crear un preprocesador que escanee una cadena en busca de dichos tokens de clase ( \p{M} o lo que sea) y los reemplace con los conjuntos de caracteres correspondientes, por lo que, para por ejemplo, \p{M} se convertiría en [\u0300–\u036F\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F] , y \P{M} se convertiría en [^\u0300–\u036F\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F] .

La gente te lo agradecería. 🙂

Tenga en cuenta que mientras \p{Ll} no tiene equivalente en las expresiones regulares de Python, \p{Zs} debe estar cubierto por '(?u)\s' . El (?u) , como dicen los documentos, “Hacer \ w, \ W, \ b, \ B, \ d, \ D, \ s y \ S depende de la base de datos de propiedades de caracteres Unicode”. Y \s significa cualquier espaciado del carácter.