这是一个小例子:
reg = ur"((?P<initial>[+\-👍])(?P<rest>.+?))$"
(在这两种情况下,文件都有 -*- 编码:utf-8 -*-
)
在 Python 2 中:
re.match(reg, u"👍hello").groupdict()
# => {u'initial': u'\ud83d', u'rest': u'\udc4dhello'}
# unicode why must you do this
而在 Python 3 中:
re.match(reg, "👍hello").groupdict()
# => {'initial': '👍', 'rest': 'hello'}
上述行为是 100% 完美的,但目前无法切换到 Python 3。在 2 中复制 3 的结果的最佳方法是什么,它适用于窄和宽 Python 构建? 👍 似乎以“\ud83d\udc4d”的格式出现,这就是让这件事变得棘手的原因。
在 Python 2 窄版中,非 BMP 字符是两个代理代码点,因此您不能在 []
语法中正确使用它们。 u'[👍]
等同于u'[\ud83d\udc4d]'
,表示“匹配其中一个\ud83d
或 \udc4d
。Python 2.7 示例:
>>> u'\U0001f44d' == u'\ud83d\udc4d' == u'👍'
True
>>> re.findall(u'[👍]',u'👍')
[u'\ud83d', u'\udc4d']
要同时修复 Python 2 和 3,请匹配 u'👍
或 [+-]
。这将在 Python 2 和 3 中返回正确的结果:
#coding:utf8
from __future__ import print_function
import re
# Note the 'ur' syntax is an error in Python 3, so properly
# escape backslashes in the regex if needed. In this case,
# the backslash was unnecessary.
reg = u"((?P<initial>👍|[+-])(?P<rest>.+?))$"
tests = u'👍hello',u'-hello',u'+hello',u'\\hello'
for test in tests:
m = re.match(reg,test)
if m:
print(test,m.groups())
else:
print(test,m)
输出(Python 2.7):
👍hello (u'\U0001f44dhello', u'\U0001f44d', u'hello')
-hello (u'-hello', u'-', u'hello')
+hello (u'+hello', u'+', u'hello')
\hello None
输出(Python 3.6):
👍hello ('👍hello', '👍', 'hello')
-hello ('-hello', '-', 'hello')
+hello ('+hello', '+', 'hello')
\hello None