Pregunta

Perl y algunos otros motores de expresiones regulares actuales soportan propiedades Unicode, tales como la categoría, en una expresión regular. P.ej. en Perl puede utilizar \p{Ll} para que coincida con una letra minúscula arbitraria o p{Zs} para cualquier separador de espacio. No veo el apoyo a esta ya sea en el 2.x 3.x ni líneas de Python (con las debidas lamenta). ¿Hay alguien al tanto de una buena estrategia para conseguir un efecto similar? soluciones propias son bienvenidos.

¿Fue útil?

Solución

¿Ha tratado Ponyguruma , un enlace de Python a la motor de expresiones regulares Oniguruma ? En ese motor se puede decir simplemente \p{Armenian} para que coincida con caracteres armenios. \p{Ll} o \p{Zs} trabajo también.

Otros consejos

Puede utilizar cuidadosamente unicodedata 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 propias, hace algún tiempo escribí un pequeño para hacer precisamente eso - convierte una categoría unicode escrita como \p{...} en un rango de valores, extraído de las href="http://unicode.org/versions/Unicode5.0.0/" unicode (v.5.0.0). Sólo las categorías son compatibles (ej .: L, Zs), y se limita a la BMP. He publicado aquí por si a alguien le resulte útil (aunque eso Oniguruma realmente parece 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
>>>

Esta es la fuente . También hay una versión de JavaScript , utilizando los mismos datos.

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

Si quieres hacer un buen corte, que sería de utilidad general, se podría crear un preprocesador que escanea una cadena para este tipo de fichas de clase (\p{M} o lo que sea) y los reemplaza con los juegos de caracteres correspondientes, de manera que, por ejemplo, , \p{M} se convertiría en [\u0300–\u036F\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F], y se convertiría en \P{M} [^\u0300–\u036F\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F].

Las personas que lo agradecerían. :)

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top