我編寫了一個程序來向Python正則表達式添加(限制)unicode support,並且它在CPython 2.5.2上工作正常,但它不能在PyPy上工作(
1.5.0-alpha0
1.8.0,實現Python
2.7.1
2.7.2),都在Windows XP上運行(編輯:在評論中看到,@ dbaupp可以在Linux上正常運行)。我不知道爲什麼,但我懷疑這與我使用u"
和ur"
有關。完整的源代碼是here,以及相關的位是:Unicode,正則表達式和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)
(上PyPy有在「實施例使用」不匹配,因此result
是None
)
,重申,程序正常工作(上CPython):Unicode數據看起來正確,替換工作按預期運行,使用示例運行正常(均通過doctest
並直接在命令行鍵入)。源文件編碼也是正確的,頭文件中的coding
指令似乎被Python識別。
PyPy做了什麼「不同」的打破我的代碼的想法?很多東西來到我的頭上(無法識別的coding
標題,命令行中的不同解釋,r
和u
的不同解釋),但就我的測試而言,CPython和PyPy似乎行爲相同,所以我對什麼接下來嘗試。
是否有任何特別的原因,你正在使用這樣一箇舊的不穩定版本的PyPy? (最新的穩定版本是1.8。) – huon
此外,給出的例子在linux2上使用'[PyPy 1.8.0 with GCC 4.4.3]「正常工作。所以看起來接下來要嘗試升級你的PyPy。 – huon
@dbaupp呃...因爲這是我的機器上安裝的? (嘿,我安裝它時它是新的......)現在,嚴重的是,我只是將它升級到了1.8.0,並且仍然獲得了相同的結果。既然你設法使它在linux上工作,那麼問題可能只限於Windows。我會進一步調查。 – mgibsonbr