如何从文本中提取所有的表情符号?

77

考虑以下列表:

a_list = ['  me así, bla es se  ds ']

如何从a_list中提取所有表情符号并将其放入新列表中?

new_lis = ['     ']

我尝试使用正则表达式,但是我没有所有可能的表情符号编码。


链接在https://dev59.com/AoTba4cB1Zd3GeqP8Zp1和https://dev59.com/UFsW5IYBdhLWcg3wFj9p。 - wim
17个回答

94
你可以使用emoji库。你可以通过检查单个代码点是否包含在emoji.UNICODE_EMOJI中来检查它是否是表情符号代码点。
import emoji

def extract_emojis(s):
  return ''.join(c for c in s if c in emoji.UNICODE_EMOJI['en'])

您可以在此处下载**#EmojiCodeSheet**中以字符串/整数格式呈现的表情符号列表,以供自定义比较器使用。 - shanraisshan
1
你的代码无法检测文本中的标志:extract_emojis(" ") - Nomiluks
1
在Python 3.6中无法工作?我得到了一个空字符串。 - Jesse Aldridge
4
Emoji.UNICODE_EMOJI现在已更改。我在执行相同任务时发现了错误。 可以使用 emoji.distinct_emoji_list(test) 其中test是字符串。 - Aminur Rahman Ashik
2
AttributeError: module 'emoji' has no attribute 'UNICODE_EMOJI' - Umair Ayub
显示剩余5条评论

48

我认为很重要的一点是指出之前的答案无法处理像 ‍‍‍ 这样的表情符号,因为它由4个表情符号组成,使用 ... in emoji.UNICODE_EMOJI 会返回4个不同的表情符号。对于像 带肤色的表情符号也是如此。

我的解决方案

引入 emojiregex 模块。正则表达式模块支持识别 字形群集(将多个Unicode代码点渲染为单个字符的序列),所以我们可以计算类似于 ‍‍‍ 的表情符号数量。

import emoji
import regex

def split_count(text):

    emoji_list = []
    data = regex.findall(r'\X', text)
    for word in data:
        if any(char in emoji.UNICODE_EMOJI['en'] for char in word):
            emoji_list.append(word)
    
    return emoji_list

测试

更多带有肤色的表情符号:

line = ["  me así, se  ds  hello ‍ emoji hello ‍‍‍ how are  you today"]

counter = split_count(line[0])
print(' '.join(emoji for emoji in counter))

输出:

      ‍ ‍‍‍   

包含标志

如果您想要包含标志,比如Unicode范围从,请添加:

flags = regex.findall(u'[\U0001F1E6-\U0001F1FF]', text) 

将上述代码添加到函数中,然后return emoji_list + flags

有关标志的更多信息,请参见《Python正则表达式匹配区域指示符字符类》中的答案。

针对更新版本的emoji

要使用emoji >= v1.2.0,您必须添加语言说明符(例如在上面的代码中使用的en):

emoji.UNICODE_EMOJI['en']

@NomanDilawar 你好,抱歉回复晚了。我已经修改了我的答案。我进行了一些测试,现在似乎可以正常工作了。 - sheldonzy
1
这是我迄今为止找到的唯一可以全面处理所有遇到的表情符号的解决方案。 - Paulo Malvar
3
另外,我认为最好写成 for grapheme in data: 而不是 for word in data:,因为它更能反映 \X 的目的。 - Amir Shabani
4
自从表情符号 v.1.2.0 版本起,检查程序必须包括一个语言说明符,例如 any(char in emoji.UNICODE_EMOJI["en"] for char in grapheme) - Alex
2
emoji.UNICODE_EMOJI['en'] 已经在 emoji >= 2.0.0 中被弃用。请改用 word in emoji.EMOJI_DATA 进行比较。 - Destaq
显示剩余3条评论

13
import emojis
new_list = emojis.get('  me así, bla es se  ds ')
print(new_list)

output>>>{'', '', '', '', '', ''}

ModuleNotFoundError: 找不到名为'emojis'的模块 - aswzen
@aswzen,但对我来说起作用了。 - Skapis9999
我的需求是先调用pip install emojis。 - aswzen
整洁的解决方案。根据我所拥有的数据,emojis.get无法识别所有表情符号,但emoji.demojize可能可以。使用advertools.extract_emoji进行了表情符号识别的交叉验证。Advertools识别的表情符号比emoji少。 - Simone
根据参考链接来看,似乎emoji.get()已经被弃用。 - Simone

11

如果不想使用外部库,作为一种Pythonic的方式,您可以简单地使用正则表达式和re.findall()来查找表情符号:

In [74]: import re
In [75]: re.findall(r'[^\w\s,]', a_list[0])
Out[75]: ['', '', '', '', '', '']

正则表达式r'[^\w\s,]'是一个排除字符类,匹配任何不是字母、数字、空白或逗号的字符。

如我在评论中提到的,文本通常包含字母数字和标点符号,这种方法可以很容易地处理它们,如果有其他情况,只需要将其手动添加到字符类中即可。请注意,由于您可以在字符类中指定一系列字符,因此您甚至可以使其更短、更灵活。

另一种解决方案是,使用接受表情符号的字符类(不带^)而非排除非表情符号字符的字符类。由于有许多表情符号具有不同的Unicode值,您只需将范围添加到字符类中即可。如果您想匹配更多表情符号,这里有一个良好的参考资源,其中包含所有标准表情符号及其不同表情符号的相应范围http://apps.timwhitlock.info/emoji/tables/unicode


1
那对于这个特定的输入是有效的,但有许多其他非表情符号字符不属于\w\s或逗号类别。 - user2357112
@user2357112 一般来说,文本通常包含单词字符和标点符号,这些可以很容易地通过这种方法处理,对于其他情况,您只需手动将它们添加到字符类中即可。请注意,由于您可以在字符类中指定字符范围,因此甚至可以使其更短、更灵活。 - Mazdak
1
你的正则表达式在所有非逗号标点符号上都失败了,还有其他问题。 - user2357112
@user2357112 嗯,这就是我说的。如果你想的话,可以将它们添加到字符类中。你不必总是包含所有情况,它是相对的,并且基于你正在处理的文本。 - Mazdak
11
手动将文本中的每个非表情符号添加到正则表达式中是一种可怕、冗长且容易出错的解决方案。 - user2357112
显示剩余2条评论

7

最高评价的答案并不总是适用的。例如,标志表情符号可能无法找到。考虑以下字符串:

s = u'Hello \U0001f1f7\U0001f1fa hello'

更好的做法是:
import emoji
emojis_list = map(lambda x: ''.join(x.split()), emoji.UNICODE_EMOJI.keys())
r = re.compile('|'.join(re.escape(p) for p in emojis_list))
print(' '.join(r.findall(s)))

5

步骤1:确保您的文本采用utf-8进行解码text.decode('utf-8')

步骤2:查找文本中的所有表情符号,您必须逐个字符分隔文本[str for str in decode]

步骤3:将所有表情符号保存在一个列表中[c for c in allchars if c in emoji.UNICODE_EMOJI] 完整示例如下:

>>> import emoji
>>> text     = "  me así, bla es se  ds "
>>> decode   = text.decode('utf-8')
>>> allchars = [str for str in decode]
>>> list     = [c for c in allchars if c in emoji.UNICODE_EMOJI]
>>> print list
[u'\U0001f914', u'\U0001f648', u'\U0001f60c', u'\U0001f495', u'\U0001f46d', u'\U0001f459']

如果您想从文本中删除内容。
>>> filtred  = [str for str in decode.split() if not any(i in str for i in list)]
>>> clean_text = ' '.join(filtred)
>>> print clean_text
me así, bla es se ds

4
另一种使用emoji的方法是使用emoji.demojize将其转换为表情符号的文本表示形式。

例如:将被转换为:grinning_face:等等...

然后查找所有:.*:模式,并对其使用emoji.emojize

# -*- coding: utf-8 -*-
import emoji
import re

text = """
Of course, too many emoji characters \
 like , #@^!*&#@^#  helps  people read aaaaaa #douchebag
"""

text = emoji.demojize(text)
text = re.findall(r'(:[^:]*:)', text)
list_emoji = [emoji.emojize(x) for x in text]
print(list_emoji)

这可能是一种冗余的方式,但它展示了如何使用emoji.emojizeemoji.demojize


3

要满足tumbleweed的需求,需要结合最佳答案和user594836的答案。以下是适用于Python 3.6的代码。

import emoji
import re

test_list=['  me así,bla es,se  ds ']

## Create the function to extract the emojis
def extract_emojis(a_list):
    emojis_list = map(lambda x: ''.join(x.split()), emoji.UNICODE_EMOJI.keys())
    r = re.compile('|'.join(re.escape(p) for p in emojis_list))
    aux=[' '.join(r.findall(s)) for s in a_list]
    return(aux)

## Execute the function
extract_emojis(test_list)

## the output
['     ']

3

首先,您需要安装这个:

conda install -c conda-forge emoji

现在我们可以编写以下代码:

import emoji
import re
text= '  me así, bla es se  ds '
text_de= emoji.demojize(text)

如果我们打印 text_de 的输出,结果如下:
':thinking_face: :see-no-evil_monkey: me así, bla es se :relieved_face: ds 
 :two_hearts::two_women_holding_hands::bikini:'

现在我们可以使用正则表达式来查找表情符号。

emojis_list_de= re.findall(r'(:[!_\-\w]+:)', text_de)
list_emoji= [emoji.emojize(x) for x in emojis_list_de]

如果我们打印lis_emoji,输出:
['', '', '', '', '', '']

所以,我们可以使用Join函数:

[''.join(list_emoji)]
OutPut: ['']

如果您想删除表情符号,可以使用以下代码:

def remove_emoji(text):
   '''
   remove all of emojis from text
   -------------------------
   '''
   text=  emoji.demojize(text)
   text= re.sub(r'(:[!_\-\w]+:)', '', text)

   return text

2

好的-我曾经遇到过同样的问题,我找到了一种解决方案,它不需要您导入任何库(如emoji或re),并且只需要一行代码。 它将返回字符串中的所有表情符号:

def extract_emojis(sentence):
    return [word for word in sentence.split() if str(word.encode('unicode-escape'))[2] == '\\' ]

这使我能够创建一个轻量级的解决方案,希望它能帮助到大家。实际上 - 我需要一个可以过滤掉字符串中任何表情符号的解决方案 - 这与上面的代码相同,但有一个小改变:

def filter_emojis(sentence):
        return [word for word in sentence.split() if str(word.encode('unicode-escape'))[2] != '\\' ]

以下是实际应用示例:

示例:

 >>> a = '  me así, bla es se  ds '
 >>> b = extract_emojis(a)
 >>> b
 ['', '', '', '']

谢谢!在所有页面的回复中,这个是最好的。 - Samuelf80

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接