¿La expresión regular de Python no coincide con la combinación de diacríticos?

Tengo una cadena UTF8 con diacríticos combinados. Quiero hacerlo coincidir con la secuencia \w regex. Coincide con los personajes que tienen acentos, pero no si hay un carácter latino con la combinación de signos diacríticos.

 >>> re.match("a\w\w\wz", u"aoooz", re.UNICODE)  >>> print u"ao\u00F3oz" aoóoz >>> re.match("a\w\w\wz", u"ao\u00F3oz", re.UNICODE)  >>> re.match("a\w\w\wz", u"aoo\u0301oz", re.UNICODE) >>> print u"aoo\u0301oz" aóooz 

(Parece que el procesador de rebajas SO está teniendo problemas con la combinación de signos diacríticos en lo anterior, pero hay un en la última línea)

¿Hay alguna forma de hacer coincidir la combinación de los diacríticos con \w ? No quiero normalizar el texto porque este texto proviene de un nombre de archivo, y no quiero tener que hacer una ‘normalización de Unicode de nombre de archivo’ todavía. Esto es Python 2.5.

Acabo de notar un nuevo paquete ” regex ” en pypi. (Si entiendo correctamente, es una versión de prueba de un nuevo paquete que algún día reemplazará el paquete stdlib re ).

Parece tener (entre otras cosas) más posibilidades con respecto a Unicode. Por ejemplo, es compatible con \X , que se usa para hacer coincidir un grafema individual (ya sea que use combinación o no). También admite la coincidencia en propiedades, bloques y secuencias de comandos de Unicode, por lo que puede usar \p{M} para referirse a las marcas de combinación. El \X mencionado anteriormente es equivalente a \P{M}\p{M}* (un carácter que NO es una marca combinada, seguido de cero o más marcas combinadas).

Tenga en cuenta que esto hace que \X más o menos el equivalente de Unicode . , no de \w , por lo que en su caso, \w\p{M}* es lo que necesita.

Es (por ahora) un paquete no stdlib, y no sé qué tan listo está (y no viene en una distribución binaria), pero es posible que desee intentarlo, ya que parece estarlo. La respuesta más fácil / más “correcta” a tu pregunta. (De lo contrario, creo que no se puede usar explícitamente los rangos de caracteres, como se describe en mi comentario a la respuesta anterior).

Consulte también esta página con información sobre expresiones regulares de Unicode, que también puede contener cierta información útil para usted (y puede servir como documentación para algunas de las cosas implementadas en el paquete de expresiones regulares).

Puede usar unicodedata.normalize para componer los diacríticos de combinación en un carácter Unicode.

 >>> import re >>> from unicodedata import normalize >>> re.match(u"a\w\w\wz", normalize("NFC", u"aoo\u0301oz"), re.UNICODE) <_sre.SRE_Match object at 0x00BDCC60> 

Sé que dijiste que no querías normalizar, pero no creo que haya un problema con esta solución, ya que solo estás normalizando la cadena para que coincida, y no tienes que cambiar el nombre del archivo en sí mismo o algo así. .