python正则表达式无法匹配特定的Unicode> 2个十六进制值

时间:2013-11-13 23:11:55

标签: python regex python-2.7 unicode

如何为大于\uFFFF的字符解析unicode“字符串”?

尝试reregex,但似乎没有正确匹配大于2个十六进制值的unicode字符。

获取任何unicode字符串(例如,以utf-8编码的推文文本)

emotes = regex.findall('[\u263A\u263B\u062A\u32E1]',tweet_json_obj['text'])
if emotes: print "Happy:{0}".format(len(emotes))

输出是文本中包含的笑脸数量,效果很好!

但如果我尝试匹配unicode字符集的表情符号: http://www.fileformat.info/info/unicode/block/emoticons/index.htm

emotes = regex.findall('[\u01F600-\u01F64F]',tweet_json_obj['text'])
if emotes: print "Emoticon:{0}".format(len(emotes))

输出是字符串中所有字符的(数字)匹配,减去空格。 正则表达式是如何匹配推文中的每个字符,或者至少看起来像string.printable?

对于大多数数据集,预期结果是0的返回值,因为我不希望人们插入这些表情符号,但它们可能......所以我想检查它们的存在。我的正则表达式不正确吗?

1 个答案:

答案 0 :(得分:2)

BMP的外部的代码点使用\Uxxxxxxxx(大写U和8个十六进制字符)。您使用\uxxxx,只使用四个十六进制字符,00不是unicode代码点的一部分:

>>> len(u'\u01f600')
3
>>> len(u'\U0001f600')
1
>>> u'\u01f600'[0]
'\u01f6'
>>> u'\u01f600'[1:]
'00'

您需要在此处使用unicode模式:

u'[\U0001F600-\U0001F64F]'

演示:

>>> import re
>>> re.search(u'[\U0001F600-\U0001F64F]', u'\U0001F600')
<_sre.SRE_Match object at 0xb73ead08>

您需要使用UCS4 Python构建,否则使用UTF16代理对实现非BMP代码点,这对正则表达式无效。

如果len(u'\U0001f600')返回2,那么您使用的是简短的UCS2版本,或者您可以查看sys.maxunicode;一个宽版本返回1114111,一个窄版本65535。

在UCS2系统上,对于这种特定情况, 可以匹配UTF16代理项和表达式:

ur'\ud83d[\ude00-\ude4f]'

这匹配构成与[\U0001F600-\U0001F64F]相同范围的UTF-16代理对,但是在窄版本上:

>>> import sys
>>> sys.maxunicode
65535
>>> import re
>>> re.search(u'\ud83d[\ude00-\ude4f]', u'\U0001F600')
<_sre.SRE_Match object at 0x105e9f5e0>