如何从 Python 中的字符串中提取表情符号和标志?


import emoji
def emoji_lis(string):
_entities = []
for pos,c in enumerate(string):
if c in emoji.UNICODE_EMOJI:
print("Matched!!", c ,c.encode('ascii',"backslashreplace"))
_entities.append({
"location":pos,
"emoji": c
})
return _entities
emoji_lis("👧🏿 مدیحہ🇵🇰  así, se 😌 ds 💕👭")
  • 匹配!! 👧 \u0001f467
  • 匹配!! 🏿 \u0001f3ff
  • 匹配!! 😌 \U0001f60c
  • 匹配!! 💕 \U0001f495
  • 匹配!! 👭 \u0001f46d

我的代码适用于所有其他表情符号,但我如何检测国旗🇵🇰?

我认为任何地方都没有库可以做到这一点。但是,这在某种程度上可以通过一个函数来完成:

U0001F1E6U0001F1E8是第一个Unicode标志,U0001F1FFU0001F1FC是最后一个,所以几乎涵盖了所有这些标志。还有 3 个会导致一些问题。

这里有一个函数可以检查输入是否是一个标志:

def is_flag_emoji(c):
return "U0001F1E6U0001F1E8" <= c <= "U0001F1FFU0001F1FC" or c in ["U0001F3F4U000e0067U000e0062U000e0065U000e006eU000e0067U000e007f", "U0001F3F4U000e0067U000e0062U000e0073U000e0063U000e0074U000e007f", "U0001F3F4U000e0067U000e0062U000e0077U000e006cU000e0073U000e007f"]

测试:

>>> is_flag_emoji('a')
False
>>> is_flag_emoji('😌')
False
>>> is_flag_emoji("""🇦🇮""")
True

因此,您可以相应地将 if 语句更改为if c in emoji.UNICODE_EMOJI or is_flag_emoji(c):

不过,这有一个问题;由于很多标志是通过连接多个字符制成的,因此您可能无法识别表情符号。

>>> s
'🇾🇪 here is more text 🇦🇩 and more'
>>>emoji_lis(s)
Matched!! 🇾 b'\U0001f1fe'
Matched!! 🇪 b'\U0001f1ea'
Matched!! 🇩 b'\U0001f1e9'
[{'location': 0, 'emoji': '🇾'}, {'location': 1, 'emoji': '🇪'}, {'location': 22, 'emoji': '🇩'}]

这是一篇关于 Unicode 如何编码国旗的文章。它们表示为两个区域指标符号的序列(代码点范围从U+1F1E6到U+1F1FF),尽管显然不是两个符号的每个可能组合都对应于一个国家(因此是一个国旗)。您可以假设不会发生"坏"组合,或者维护(或导入)具有(当前)270 个有效符号对的集合。

然后是地区旗帜。这些表示为黑色标志代码点 (U+1F3F4),后跟一系列标记(代码点 U+E0001,范围从 U+E0020 到 U+E007F),拼写区域标识符(例如,对于标志或威尔士,将是"gbwls"),加上"取消标记"代码点 (U+E007F)。

而且,除此之外,你当然还有看起来像旗帜的常规表情符号。前面提到的黑旗(U+1F3F4)就是其中之一,但你也有三角旗(U+1F6A9)等。其中大多数您应该已经能够检测到,因为它们就像其他表情符号一样。但是,我们在这里还没有完全完成。您有复合表情符号的问题,它会影响某些标志,但也会影响许多其他表情符号。在您的示例中,您可以看到输入字符串中黑人女性的匹配表情符号是一个"基本"女性表情符号,然后是这个棕色补丁。这是因为黑人女性表情符号由两个代码点组成,女人(U+1F469)和深色肤色(U+1F311)。在许多其他情况下,您需要两个代码点,加上两者之间的零宽度连接器 (U+200D),以指定要合并它们。有时你还需要加入一个变体选择器(通常为 16,U+FE0F)来表明您希望将内容用作表情符号。您可以在本文中阅读有关此内容的更多信息。在标志的情况下,例如彩虹旗(U+1F3F3、U+FE0F、U+200D、U+1F308),其内容为"白旗,变体选择器 16(使用白旗表情符号,而不是文本),零宽度连接器,彩虹";或海盗旗(U+1F3F4,U+200D,U+2620,U+FE0F),其内容为"黑旗,零宽度细木工,骷髅头和交叉骨,变体选择器16(使用骷髅头和十字骨表情符号,而不是文本)"。

现在,有不同的方法可以处理所有这些,但是在当前的方法中,您一次迭代一个代码点,因此您将无法检测到复杂的表情符号。您可以拥有一大组所有有趣的序列(标志,一些复合表情符号等),并在输入中查找它们。您可以检查当前字符是否是区域指示器符号,如果是这种情况,请尝试读取下一个代码点以形成一个标志(其余部分则使用单个简单的表情符号)。我不确定适合您的情况的最佳解决方案是什么(在复杂性/收益权衡方面),但您应该了解表情符号编码的细微差别以及您可能会发现的陷阱。