替换给定unicode字符串中的所有表情符号

时间:2018-11-19 22:20:04

标签: regex python-2.7 unicode

我有一个emoji包中的Unicode符号列表。我的最终目标是创建一个函数,该函数以unicode作为字符串的输入,即something,然后删除所有表情符号,即"something"。以下是我要实现的目标的演示:

from emoji import UNICODE_EMOJI
text = 'something'
exclude_list = UNICODE_EMOJI.keys()
output = ... = 'something'

我一直在尝试执行上述操作,在此过程中,我遇到了一种奇怪的行为,如下所示,如您所见。我相信,如果下面的代码是固定的,那么我将能够实现自己的最终目标。

import regex as re
print u'\U0001F469'                     #    
print u'\U0001F60C'                     #     
print u'\U0001F469\U0001F60C'           #  

text = u'some\U0001F469\U0001F60Cthing' 
print text                              # something

# Removing "" works
print re.sub(ur'[\U0001f469\U0001F60C]+', u'', text)  # something
# Removing only "" doesn't work 
print re.sub(ur'[\U0001f469]+', u'', text)            # some�thing

3 个答案:

答案 0 :(得分:3)

在大多数Python 2.7版本中,高于0x10000的Unicode代码点被编码为surrogate pair,这意味着Python实际上将它们视为两个字符。您可以使用len(u'\U0001F469')向自己证明这一点。

解决此问题的最佳方法是移至Python版本,该版本将这些代码点适当地视为单个实体,而不是代理对。您可以为此编译Python 2.7,而最新版本的Python 3会自动进行编译。

要创建用于replace的正则表达式,只需将所有字符与|连接在一起。由于字符列表已经使用代理对进行编码,因此它将创建正确的字符串。

subs = u'|'.join(exclude_list)
print re.sub(subs, u'', text)

答案 1 :(得分:2)

旧的2.7正则表达式引擎感到困惑,原因是:

  1. Python 2.7使用基于单词的强制Unicode存储,其中某些Unicode代码点会自动由代理对替代。

  2. 在正则表达式“看到”您的Python字符串之前,Python已经帮助您将大型Unicode代码点解析为两个单独的字符(每个字符本身都是有效的但不完整的单个Unicode字符)。

  3. 这意味着[\U0001f469]+'替换了某物(一个2个字符的字符类),但是其中一个在您的字符串中,另一个不在。这会导致您的输出格式不正确。

此问题已解决:

print re.sub(ur'(\U0001f469|U0001F60C)+', u'', text)  # something
# Removing only "" doesn't work 
print re.sub(ur'(\U0001f469)+', u'', text)            # some�thing
# .. and now it does:
something

因为现在正则表达式引擎可以看到您正在寻找的完全相同的字符序列(代理对或其他字符)。

如果您想从exclude_list中删除所有表情符号,则可以显式循环其内容并一一替换:

exclude_list = UNICODE_EMOJI.keys()

for bad in exclude_list:  # or simply "for bad in UNICODE_EMOJI" if you gotta catch them all
    if bad in text:
        print 'Removing '+bad
        text = text.replace(bad, '')
Removing 
Removing 
something

(这也将中间结果显示为有效的证明;您只需要在循环中使用replace行即可。)

答案 2 :(得分:2)

要使用当前方法从输入字符串中删除所有表情符号,请使用

import re
from emoji import UNICODE_EMOJI
text = u'something'
exclude_list = UNICODE_EMOJI.keys()
rx = ur"(?:{})+".format("|".join(map(re.escape,exclude_list)))
print re.sub(rx, u'', text)
# => u'something'

如果您没有re.escape表情符号字符,则会由于文字字符与组内的交替运算符混淆而出现nothing to repeat错误,因此需要map(re.escape,exclude_list)。 / p>

经过Python 2.7.12测试(默认,2018年11月12日,14:36:49) linux2上的[GCC 5.4.0 20160609]。