Escribí un programa para agregar (limitado) unicode support a las expresiones regulares de Python, y aunque funciona bien en CPython 2.5.2 no funciona en PyPy (
1.5.0-alpha0
1.8.0, la implementación de Python 2.7.1
2.7.2), ambos se ejecutan en Windows XP (Editar: como se ve en los comentarios, @dbaupp podría ejecutarlo bien en Linux). No tengo idea de por qué, pero sospecho que tiene algo que ver con mis usos de u"
y ur"
. La fuente completo es here, y los bits relevantes son:Unicode, expresiones regulares y PyPy
# -*- coding:utf-8 -*-
import re
# Regexps to match characters in the BMP according to their Unicode category.
# Extracted from Unicode specification, version 5.0.0, source:
# http://unicode.org/versions/Unicode5.0.0/
unicode_categories = {
ur'Pi':ur'[\u00ab\u2018\u201b\u201c\u201f\u2039\u2e02\u2e04\u2e09\u2e0c\u2e1c]',
ur'Sk':ur'[\u005e\u0060\u00a8\u00af\u00b4\u00b8\u02c2-\u02c5\u02d2-\u02df\u02...',
ur'Sm':ur'[\u002b\u003c-\u003e\u007c\u007e\u00ac\u00b1\u00d7\u00f7\u03f6\u204...',
...
ur'Pf':ur'[\u00bb\u2019\u201d\u203a\u2e03\u2e05\u2e0a\u2e0d\u2e1d]',
ur'Me':ur'[\u0488\u0489\u06de\u20dd-\u20e0\u20e2-\u20e4]',
ur'Mc':ur'[\u0903\u093e-\u0940\u0949-\u094c\u0982\u0983\u09be-\u09c0\u09c7\u0...',
}
def hack_regexp(regexp_string):
for (k,v) in unicode_categories.items():
regexp_string = regexp_string.replace((ur'\p{%s}' % k),v)
return regexp_string
def regex(regexp_string,flags=0):
"""Shortcut for re.compile that also translates and add the UNICODE flag
Example usage:
>>> from unicode_hack import regex
>>> result = regex(ur'^\p{Ll}\p{L}*').match(u'áÇñ123')
>>> print result.group(0)
áÇñ
>>>
"""
return re.compile(hack_regexp(regexp_string), flags | re.UNICODE)
(en PyPy no hay ninguna coincidencia en el "Ejemplo de uso", por lo result
es None
)
Reiterando, el programa funciona bien (en CPython): los datos Unicode parecen correctos, el reemplazo funciona según lo previsto, el ejemplo de uso se ejecuta correctamente (ambos a través de doctest
y escribiéndolo directamente en la línea de comandos). La codificación del archivo fuente también es correcta, y la directiva coding
en el encabezado parece ser reconocida por Python.
¿Alguna idea de lo que PyPy hace "diferente" que está rompiendo mi código? Muchas cosas vinieron a mi cabeza (encabezado coding
no reconocido, diferentes codificaciones en la línea de comandos, diferentes interpretaciones de r
y u
) pero en lo que respecta a mis pruebas, tanto CPython como PyPy parecen comportarse de forma idéntica, así que no tengo ni idea de qué prueba a continuación.
¿Hay alguna razón en particular por la que está utilizando una versión tan inestable de PyPy? (La última versión estable es 1.8.) – huon
Además, el ejemplo dado funciona bien para mí usando '[PyPy 1.8.0 con GCC 4.4.3] en linux2'. Por lo tanto, parece que lo que debe probar a continuación es actualizar su PyPy. – huon
@dbaupp uh ...porque eso es lo que está instalado en mi máquina? (hey, era nuevo cuando lo instalé ...) Ahora, en serio, acabo de actualizarlo a 1.8.0 y aún obtengo los mismos resultados. Como logró hacer que funcione en Linux, tal vez el problema esté restringido a Windows. Investigaré más a fondo. – mgibsonbr