从Unicode字符串中正确提取表情符号 [英] Correctly extract Emojis from a Unicode string

查看:18
本文介绍了从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

现在,根据Python: getting correct string length when it contains surrogate pairsPython returns length of 2 for single Unicode character string,在Python2"窄"版本中(使用sys.maxunicode==65535),32位Unicode字符表示为surrogate pairs,这对字符串函数是不透明的。仅在3.3(PEP0393)中修复了此问题。

最简单的解决方案(除了迁移到3.3+)是从第三个链接中概述的源代码编译一个Python"宽"版本。在这个版本中,Unicode字符都是4字节(因此可能会占用大量内存),但如果您需要常规地处理宽Unicode字符,这可能是一个可以接受的价格。

"窄"构建的解决方案是创建一组自定义的字符串函数(lenslice;可能作为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆