作者:百度地震姜常宏 | 来源:互联网 | 2022-12-08 09:56
我正在尝试从Unicode文本中仅删除表情符号。我尝试了另一种Stack Overflow帖子中介绍的各种方法,但是这些方法都没有完全删除所有表情符号/笑脸。例如:
解决方案1:
def remove_emoji(self, string):
emoji_pattern = re.compile("["
u"\U0001F600-\U0001F64F" # emoticons
u"\U0001F300-\U0001F5FF" # symbols & pictographs
u"\U0001F680-\U0001F6FF" # transport & map symbols
u"\U0001F1E0-\U0001F1FF" # flags (iOS)
u"\U00002702-\U000027B0"
u"\U000024C2-\U0001F251"
"]+", flags=re.UNICODE)
return emoji_pattern.sub(r'', string)
在以下示例中进入:
Input: ??????? ????? ???????
Output: ??????? ????? ???????
另一个尝试,解决方案2:
def deEmojify(self, inputString):
returnString = ""
for character in inputString:
try:
character.encode("ascii")
returnString += character
except UnicodeEncodeError:
returnString += ''
return returnString
导致删除任何非英文字符:
Input: Test????? ??????? A.P&T.S.
Output: Test A.P&T.S.
它不仅删除了所有表情符号,而且还删除了非英文字符character.encode("ascii")
;我的非英语输入无法编码为ASCII。
有什么方法可以从国际Unicode文本中正确删除Emoji吗?
1> Martijn Piet..:
正则表达式已过时。它似乎涵盖了Emoji定义的Unicode 8.0之前的版本(因为Unicode 9.0中添加了U + 1F91D HANDSHAKE)。另一种方法只是强制编码为ASCII的效率非常低下的方法,而只是删除Emoji时,这几乎不是您想要的(并且可以使用更加轻松,高效地实现text.encode('ascii', 'ignore').decode('ascii')
)。
如果您需要最新的正则表达式,请从积极尝试使Emoji保持最新状态的软件包中获取一个;它特别支持生成这样的正则表达式:
import emoji
def remove_emoji(text):
return emoji.get_emoji_regexp().sub(u'', text)
该软件包当前是Unicode 11.0的最新版本,并具有可以快速更新到将来发行版的基础结构。您的项目要做的就是在有新版本时进行升级。
使用示例输入进行演示:
>>> print(remove_emoji(u'??????? ????? ??????? '))
??????? ????? ???????
>>> print(remove_emoji(u'Test????? ??????? A.P&T.S. '))
Test????? ??????? A.P&T.S.
需要注意的是在正则表达式的作品Unicode文本,为Python 2请确保您有从解码str
到unicode
,为Python 3,bytes
到str
第一。
表情符号这些天是复杂的野兽。以上内容将删除完整的有效表情符号。如果您有“不完整”的Emoji表情组件,例如肤色代码点(仅希望与特定的 Emoji表情结合使用),则在删除这些表情符时会遇到更多麻烦。肤色代码点很容易(之后只删除这5个代码点),但是有很多组合由无辜的字符组成,例如?。U + 2640女性符号或?U + 2642 MALE SIGN以及变体选择器和U + 200D零宽度JOINER在其他情况下也具有特定含义,并且您不能只对它们进行正则表达式,除非您不介意使用Devanagari,Kannada或CJK表意文字打断文本,仅举几个例子。
也就是说,以下Unicode 11.0代码点可能可以安全地删除(基于过滤Emoji_Component
Emoji-data名称):
20E3 ; (?) combining enclosing keycap
FE0F ; () VARIATION SELECTOR-16
1F1E6..1F1FF ; (..) regional indicator symbol letter a..regional indicator symbol letter z
1F3FB..1F3FF ; (..) light skin tone..dark skin tone
1F9B0..1F9B3 ; (..) red-haired..white-haired
E0020..E007F ; (..) tag space..cancel tag
可以通过创建一个新的正则表达式来匹配它们来删除它:
import re
try:
uchr = unichr # Python 2
import sys
if sys.maxunicode == 0xffff:
# narrow build, define alternative unichr encoding to surrogate pairs
# as unichr(sys.maxunicode + 1) fails.
def uchr(codepoint):
return (
unichr(codepoint) if codepoint <= sys.maxunicode else
unichr(codepoint - 0x010000 >> 10 | 0xD800) +
unichr(codepoint & 0x3FF | 0xDC00)
)
except NameError:
uchr = chr # Python 3
# Unicode 11.0 Emoji Component map (deemed safe to remove)
_removable_emoji_compOnents= (
(0x20E3, 0xFE0F), # combining enclosing keycap, VARIATION SELECTOR-16
range(0x1F1E6, 0x1F1FF + 1), # regional indicator symbol letter a..regional indicator symbol letter z
range(0x1F3FB, 0x1F3FF + 1), # light skin tone..dark skin tone
range(0x1F9B0, 0x1F9B3 + 1), # red-haired..white-haired
range(0xE0020, 0xE007F + 1), # tag space..cancel tag
)
emoji_compOnents= re.compile(u'({})'.format(u'|'.join([
re.escape(uchr(c)) for r in _removable_emoji_components for c in r])),
flags=re.UNICODE)
然后更新上面的remove_emoji()
函数以使用它:
def remove_emoji(text, remove_compOnents=False):
cleaned = emoji.get_emoji_regexp().sub(u'', text)
if remove_components:
cleaned = emoji_components.sub(u'', cleaned)
return cleaned
@ascii_walker:是的,我假设使用Python 3(Python 2.7非常接近生命终结,您应该真正考虑升级!)。正则表达式针对Unicode文本,因为UTF-8序列打开了另一批巨大的蠕虫,所以正则表达式中处理了表情符号。我今天不去那里。