从Unicode字符串中正确提取表情符号 [英] Correctly extract Emojis from a Unicode string
本文介绍了从Unicode字符串中正确提取表情符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我使用的是Python2,我有一个包含表情符号以及其他Unicode字符的字符串。我需要将其转换为列表,其中列表中的每个条目都是单个字符/表情符号。
x = u'😘😘xyz😊😊'
char_list = [c for c in x]
所需输出为:
['😘', '😘', 'x', 'y', 'z', '😊', '😊']
实际输出为:
[u'ud83d', u'ude18', u'ud83d', u'ude18', u'x', u'y', u'z', u'ud83d', u'ude0a', u'ud83d', u'ude0a']
如何获得所需的输出?
推荐答案
首先,在Python2中,您需要使用unicode字符串(u'<...>'
)才能将unicode字符视为unicode字符。如果要使用字符本身而不是源代码中的UXXXXXXXX
表示形式,则correct source encoding。
sys.maxunicode==65535
),32位Unicode字符表示为surrogate pairs,这对字符串函数是不透明的。仅在3.3(PEP0393)中修复了此问题。
最简单的解决方案(除了迁移到3.3+)是从第三个链接中概述的源代码编译一个Python"宽"版本。在这个版本中,Unicode字符都是4字节(因此可能会占用大量内存),但如果您需要常规地处理宽Unicode字符,这可能是一个可以接受的价格。
"窄"构建的解决方案是创建一组自定义的字符串函数(len
,slice
;可能作为unicode
的子类)来检测代理项对并将它们作为单个字符进行处理。我不容易找到一个现有的(这很奇怪),但它并不太难写:
- 根据UTF-16#U+10000 to U+10FFFF - Wikipedia,
- 第一个字符(高代理项)在
0xD800..0xDBFF
范围内
- 第二个字符(低代理项)-范围
0xDC00..0xDFFF
- 这些范围是保留的,因此不能作为常规字符出现
- 第一个字符(高代理项)在
下面是检测代理项对的代码:
def is_surrogate(s,i):
if 0xD800 <= ord(s[i]) <= 0xDBFF:
try:
l = s[i+1]
except IndexError:
return False
if 0xDC00 <= ord(l) <= 0xDFFF:
return True
else:
raise ValueError("Illegal UTF-16 sequence: %r" % s[i:i+2])
else:
return False
和一个返回简单切片的函数:
def slice(s,start,end):
l=len(s)
i=0
while i<start and i<l:
if is_surrogate(s,i):
start+=1
end+=1
i+=1
i+=1
while i<end and i<l:
if is_surrogate(s,i):
end+=1
i+=1
i+=1
return s[start:end]
在这里,您付出的代价是性能,因为这些函数比内置函数慢得多:
>>> ux=u"a"*5000+u"U00100000"*30000+u"b"*50000
>>> timeit.timeit('slice(ux,10000,100000)','from __main__ import slice,ux',number=1000)
46.44128203392029 #msec
>>> timeit.timeit('ux[10000:100000]','from __main__ import slice,ux',number=1000000)
8.814016103744507 #usec
这篇关于从Unicode字符串中正确提取表情符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文