将表情符号视为正则表达式中的一个字符

时间:2018-01-16 05:53:36

标签: python regex python-2.7 python-unicode unicode-literals

这是一个小例子:

reg = ur"((?P<initial>[+\-])(?P<rest>.+?))$"

(在这两种情况下,文件都有-*- coding: 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。什么是复制3的结果的最佳方法2,适用于窄版和宽版Python?似乎是以“&#34; \ ud83d \ udc4d&#34;”的格式来找我,这就是让这个变得棘手的事情。

4 个答案:

答案 0 :(得分:3)

只需使用u前缀。

在Python 2.7中:

>>> reg = u"((?P<initial>[+\-])(?P<rest>.+?))$"
>>> re.match(reg, u"hello").groupdict()
{'initial': '', 'rest': 'hello'}

答案 1 :(得分:3)

在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

答案 2 :(得分:1)

在python 2.7中有一个选项可以将该unicode转换为表情符号:

b = dict['vote'] # assign that unicode value to b 
print b.decode('unicode-escape')

我不知道这正是你正在寻找的东西。但我认为你可以用某种方式来解决这个问题。

答案 3 :(得分:1)

这是因为Python2没有区分字节和unicode字符串。

请注意,Python 2.7解释器将字符表示为4个字节。要在Python 3中获得相同的行为,必须将unicode字符串显式转换为bytes对象。

# Python 2.7
>>> s = "hello"
>>> s
'\xf0\x9f\x91\x8dhello'

# Python 3.5
>>> s = "hello"
>>> s
'hello'

因此,对于Python 2,只需将该字符的十六进制表示用于搜索模式(包括指定长度),它就可以工作。

>>> reg = "((?P<initial>[+\-\xf0\x9f\x91\x8d]{4})(?P<rest>.+?))$"
>>> re.match(reg, s).groupdict()
{'initial': '\xf0\x9f\x91\x8d', 'rest': 'hello'}