从Unicode字符串中正确提取表情符号

从Unicode字符串中正确提取表情符号,第1张

从Unicode字符串中正确提取表情符号

首先,在Python2中,您需要使用Unipre字符串

u'<...>'
)将Unipre字符视为Unipre字符。而且正确的源编码,如果你想使用的字符本身,而不是
UXXXXXXXX
在源代码表示。

现在,按照Python:在包含代理对时获取正确的字符串长度,并且Python为单个Unipre字符串返回2的长度,在Python2“
narrow”构建中(带有

sys.maxunipre==65535
),将32位Unipre字符表示为代理对,对字符串函数不是透明的。仅在3.3(PEP0393)中已解决此问题。

最简单的解决方案(用于迁移到3.3+的保存)是从源代码编译Python“宽”版,如第3条链接所述。
在其中,Unipre字符全为4字节(因此是潜在的内存消耗),但是如果您需要例行处理宽的Unipre字符,这可能是可以接受的价格。

“缩小”构建的解决方案创建一组自定义的字符串函数

len
slice
;可能作为的子类
unipre
),该 函数
将检测代理对并将其作为单个字符处理。我无法轻易找到一个现有的(这很奇怪),但是写起来并不难:

  • 根据UTF-16#U + 10000至U + 10FFFF-维基百科,
    • 第一个字符 (高替代) 在范围内
      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


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5647549.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存