从 Python 中的字符串中删除表情符号

removing emojis from a string in Python

我在 Python 中找到了这段用于删除表情符号的代码,但它不起作用。你能帮忙处理其他代码或解决这个问题吗?

我观察到我所有的 emjois 都以 \xf 开头,但是当我尝试搜索 str.startswith("\xf") 时,出现无效字符错误。

emoji_pattern = r'/[x{1F601}-x{1F64F}]/u'
re.sub(emoji_pattern, '', word)

这是错误:

Traceback (most recent call last):
  File "test.py", line 52, in <module>
    re.sub(emoji_pattern,'',word)
  File "/usr/lib/python2.7/re.py", line 151, in sub
    return _compile(pattern, flags).sub(repl, string, count)
  File "/usr/lib/python2.7/re.py", line 244, in _compile
    raise error, v # invalid expression
sre_constants.error: bad character range

列表中的每一项都可以是一个单词['This', 'dog', '\xf0\x9f\x98\x82', 'https://t.co/5N86jYipOI']

更新: 我使用了其他代码:

emoji_pattern=re.compile(ur" " " [\U0001F600-\U0001F64F] # emoticons \
                                 |\
                                 [\U0001F300-\U0001F5FF] # symbols & pictographs\
                                 |\
                                 [\U0001F680-\U0001F6FF] # transport & map symbols\
                                 |\
                                 [\U0001F1E0-\U0001F1FF] # flags (iOS)\
                          " " ", re.VERBOSE)

emoji_pattern.sub('', word)

但这仍然没有删除表情符号并显示它们!任何线索为什么会这样?

因为 [...] 表示一组字符中的任何一个,并且因为一组中用破折号分隔的两个字符表示一个字符范围(通常,"a-z" 或“0-9” ), 你的模式说 "a slash, followed by any characters in the group containing x, {, 1, F, 6, 0, 1, the range } through x, {, 1, F, 6, 4, f or }" 后跟一个斜杠和字母 u”。中间的范围就是所谓的坏字符范围。

在 Python 2 上,您必须使用 u'' 文字来创建 Unicode 字符串。此外,您应该传递 re.UNICODE 标志并将输入数据转换为 Unicode(例如,text = data.decode('utf-8')):

#!/usr/bin/env python
import re

text = u'This dog \U0001f602'
print(text) # with emoji

emoji_pattern = re.compile("["
        u"\U0001F600-\U0001F64F"  # emoticons
        u"\U0001F300-\U0001F5FF"  # symbols & pictographs
        u"\U0001F680-\U0001F6FF"  # transport & map symbols
        u"\U0001F1E0-\U0001F1FF"  # flags (iOS)
                           "]+", flags=re.UNICODE)
print(emoji_pattern.sub(r'', text)) # no emoji

输出

This dog 
This dog 

注意:emoji_pattern 仅匹配部分表情符号(并非全部)。参见 Which Characters are Emoji

如果您使用的是已接受答案中的示例,但仍然出现 "bad character range" 错误,那么您可能使用的是窄版本( 了解更多详细信息)。似乎有效的正则表达式的重新格式化版本是:

emoji_pattern = re.compile(
    u"(\ud83d[\ude00-\ude4f])|"  # emoticons
    u"(\ud83c[\udf00-\uffff])|"  # symbols & pictographs (1 of 2)
    u"(\ud83d[\u0000-\uddff])|"  # symbols & pictographs (2 of 2)
    u"(\ud83d[\ude80-\udeff])|"  # transport & map symbols
    u"(\ud83c[\udde0-\uddff])"  # flags (iOS)
    "+", flags=re.UNICODE)

接受的答案,其他人为我工作了一点,但我最终决定去除 Basic Multilingual Plane 之外的所有字符。这不包括未来添加到其他 Unicode 平面(表情符号等存在的地方),这意味着每次添加新的 Unicode 字符时我都不必更新我的代码:)。

在 Python 2.7 中,如果您的文本尚未转换为 unicode,然后使用下面的否定正则表达式(替换任何内容 not 在正则表达式中,它是 BMP 除了 用于代理的所有字符,用于创建 2 字节 Supplementary Multilingual Plane 字符) .

NON_BMP_RE = re.compile(u"[^\U00000000-\U0000d7ff\U0000e000-\U0000ffff]", flags=re.UNICODE)
NON_BMP_RE.sub(u'', unicode(text, 'utf-8'))

删除表情符号的完整版本:

import re
def remove_emoji(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)

尝试了所有的答案,不幸的是,他们没有删除新的拥抱表情符号或碰杯表情符号或,等等。

最后列出了所有可能的表情符号,取自 github 上的 python 表情符号包,我不得不创建一个要点,因为 Whosebug 答案有 30k 个字符的限制,它是超过 70k 个字符。

我正在通过@jfs 更新我对此的回答,因为我之前的回答未能说明其他 Unicode 标准,如拉丁语、希腊语等。Whosebug 不允许我删除我之前的回答,因此我将其更新为匹配问题的最可接受的答案。

#!/usr/bin/env python
import re

text = u'This is a smiley face \U0001f602'
print(text) # with emoji

def deEmojify(text):
    regrex_pattern = re.compile(pattern = "["
        u"\U0001F600-\U0001F64F"  # emoticons
        u"\U0001F300-\U0001F5FF"  # symbols & pictographs
        u"\U0001F680-\U0001F6FF"  # transport & map symbols
        u"\U0001F1E0-\U0001F1FF"  # flags (iOS)
                           "]+", flags = re.UNICODE)
    return regrex_pattern.sub(r'',text)

print(deEmojify(text))

这是我之前的回答,请勿使用。

def deEmojify(inputString):
    return inputString.encode('ascii', 'ignore').decode('ascii')

如果您不热衷于使用正则表达式,最好的解决方案可能是使用 emoji python package.

这里是一个简单的函数,用于 return 表情符号自由文本(感谢这个 ):

import emoji
def give_emoji_free_text(text):
    allchars = [str for str in text.decode('utf-8')]
    emoji_list = [c for c in allchars if c in emoji.UNICODE_EMOJI]
    clean_text = ' '.join([str for str in text.decode('utf-8').split() if not any(i in str for i in emoji_list)])
    return clean_text

如果您要处理包含表情符号的字符串,这很简单

>> s1 = "Hi  How is your  and . Have a nice weekend "
>> print s1
Hi  How is your  and . Have a nice weekend 
>> print give_emoji_free_text(s1)
Hi How is your and Have a nice weekend

如果您正在处理 unicode(如@jfs 的例子),只需使用 utf-8 编码即可。

>> s2 = u'This dog \U0001f602'
>> print s2
This dog 
>> print give_emoji_free_text(s2.encode('utf8'))
This dog

编辑

根据评论,应该很简单:

def give_emoji_free_text(text):
    return emoji.get_emoji_regexp().sub(r'', text.decode('utf8'))

这是我的解决方案。此解决方案删除了​​可由 python ‍♂ 和 ‍♀

呈现的额外男女表情符号
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"
                       u"\U0001f926-\U0001f937"
                       u"\u200d"
                       u"\u2640-\u2642" 
                       "]+", flags=re.UNICODE)

像这样将字符串转换成另一个字符集可能会有所帮助:

text.encode('latin-1', 'ignore').decode('latin-1')

亲切的问候。

我试图收集完整的 unicode 列表。 我用它从推文中提取表情符号,对我来说效果很好。

# Emojis pattern
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"
                u"\U0001f926-\U0001f937"
                u'\U00010000-\U0010ffff'
                u"\u200d"
                u"\u2640-\u2642"
                u"\u2600-\u2B55"
                u"\u23cf"
                u"\u23e9"
                u"\u231a"
                u"\u3030"
                u"\ufe0f"
    "]+", flags=re.UNICODE)

这是一个使用表情符号库 get_emoji_regexp() 的 Python 3 脚本 - 正如 kingmakerking 和 Martijn Pieters 在他们的 answer/comment.

中所建议的

它从文件中读取文本并将无表情符号的文本写入另一个文件。

import emoji
import re


def strip_emoji(text):

    print(emoji.emoji_count(text))

    new_text = re.sub(emoji.get_emoji_regexp(), r"", text)

    return new_text


with open("my_file.md", "r") as file:
    old_text = file.read()

no_emoji_text = strip_emoji(old_text)

with open("file.md", "w+") as new_file:
    new_file.write(no_emoji_text)

去除表情符号完整版

import re
def remove_emojis(data):
    emoj = re.compile("["
        u"\U0001F600-\U0001F64F"  # emoticons
        u"\U0001F300-\U0001F5FF"  # symbols & pictographs
        u"\U0001F680-\U0001F6FF"  # transport & map symbols
        u"\U0001F1E0-\U0001F1FF"  # flags (iOS)
        u"\U00002500-\U00002BEF"  # chinese char
        u"\U00002702-\U000027B0"
        u"\U00002702-\U000027B0"
        u"\U000024C2-\U0001F251"
        u"\U0001f926-\U0001f937"
        u"\U00010000-\U0010ffff"
        u"\u2640-\u2642" 
        u"\u2600-\u2B55"
        u"\u200d"
        u"\u23cf"
        u"\u23e9"
        u"\u231a"
        u"\ufe0f"  # dingbats
        u"\u3030"
                      "]+", re.UNICODE)
    return re.sub(emoj, '', data)

最好的解决方案是使用外部库 emoji。该库不断更新最新的表情符号,因此可用于在任何文本中查找它们。与删除所有 unicode 字符的 ascii 解码方法不同,此方法保留它们并且仅删除表情符号。

  1. 如果没有,请先安装表情符号库:pip install emoji
  2. 接下来将其导入到您的 file/project 中:import emoji
  3. 现在要删除所有表情符号,请使用以下语句: emoji.get_emoji_regexp().sub("", msg) 其中 msg 是要编辑的文本

这就是你所需要的。

我知道这可能与提出的问题没有直接关系,但它有助于解决从文本中删除表情符号的父问题。 python 中有一个名为 demoji 的模块,它非常准确地完成了这项任务,并删除了几乎所有类型的表情符号。它还会定期更新以提供最新的表情符号删除支持。 删除表情符号使用 demoji.replace(text, '')

对我来说,以下在 python 3.8 中用于替换表情符号:

import re
result = re.sub('[(\U0001F600-\U0001F92F|\U0001F300-\U0001F5FF|\U0001F680-\U0001F6FF|\U0001F190-\U0001F1FF|\U00002702-\U000027B0|\U0001F926-\U0001FA9F|\u200d|\u2640-\u2642|\u2600-\u2B55|\u23cf|\u23e9|\u231a|\ufe0f)]+','','A quick brown fox jumps over the lazy dog')

它是此处给出的答案的简化版本。 我测试了此代码的 i18n 支持,测试了英语、俄语、中文和日语。仅删除了表情符号。

这不是一个详尽的列表,可能遗漏了一些表情符号,但适用于大多数常见的表情符号

这是删除所有表情符号的最简单代码。

import emoji

def remove_emojis(text: str) -> str:
    return ''.join(c for c in text if c not in emoji.UNICODE_EMOJI)

pip install emoji

我只是使用正则表达式删除了所有特殊字符,这对我有用。

sent_0 = re.sub('[^A-Za-z0-9]+', ' ', sent_0)

对于仍在使用 Python 2.7 的用户,此 regex 可能会有所帮助:

(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|[\ud83c\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|[\ud83c\ude32-\ude3a]|[\ud83c\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])

所以要在您的代码中使用它,它会有点像这样:

emoji_pattern = re.compile(
    u"(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|[\ud83c\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|[\ud83c\ude32-\ude3a]|[\ud83c\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])"
    "+", flags=re.UNICODE)

现在我们实际上不再使用 Python 2.7 了,为什么还需要这个? 一些systems/Python 实现仍然使用 Python 2.7,例如 Amazon Redshift 中的 Python UDF。

我可以通过以下方式摆脱表情符号。

表情符号安装 https://pypi.org/project/emoji/

$ pip3 install emoji
import emoji

def remove_emoji(string):
    return emoji.get_emoji_regexp().sub(u'', string)

emojis = '(`ヘ´) ⭕⭐⏩'
print(remove_emoji(emojis))

## Output result
(`ヘ´)

使用 Demoji 包, https://pypi.org/project/demoji/

import demoji

text=""
emoji_less_text = demoji.replace(text, "")

这不仅仅是过滤掉表情符号。它删除了 unicode,但尝试以温和的方式执行此操作,并在可能的情况下将其替换为相关的 ASCII 字符。如果您的文本中没有例如十几个不同的 unicode 撇号和 unicode 引号(通常来自 Apple 手持设备),而只有常规的 ASCII 撇号和引号,这在未来可能是一件幸事。

unicodedata.normalize("NFKD", sentence).encode("ascii", "ignore")

这很稳健,我用它和更多的守卫一起使用:

import unicodedata

def neutralize_unicode(value):
    """
    Taking care of special characters as gently as possible

    Args:
        value (string): input string, can contain unicode characters

    Returns:
        :obj:`string` where the unicode characters are replaced with standard
        ASCII counterparts (for example en-dash and em-dash with regular dash,
        apostrophe and quotation variations with the standard ones) or taken
        out if there's no substitute.
    """
    if not value or not isinstance(value, basestring):
        return value

    if isinstance(value, str):
        return value

    return unicodedata.normalize("NFKD", value).encode("ascii", "ignore")

这是python 2.

我找到了 2 个库来替换表情符号:

表情符号https://pypi.org/project/emoji/

import emoji
string = "  "
emoji.replace_emoji(string, replace="!")

表情符号https://pypi.org/project/demoji/

import demoji
string = "  "
demoji.replace(string, repl="!")

他们还有其他有用的方法