【问题标题】:remove unicode emoji using re in python在 python 中使用 re 删除 unicode emoji
【发布时间】:2014-12-21 12:28:10
【问题描述】:

我尝试从 unicode 推文文本中删除表情符号并使用 python 2.7 打印出结果

myre = re.compile(u'[\u1F300-\u1F5FF\u1F600-\u1F64F\u1F680-\u1F6FF\u2600-\u26FF\u2700-\u27BF]+',re.UNICODE)
print myre.sub('', text)

但似乎几乎所有字符都从文本中删除了。我已经检查了其他帖子的几个答案,不幸的是,它们在这里都不起作用。我在 re.compile() 中做错了吗?

这是一个删除所有字符的示例输出:

“   '   //./” ! # # # …

【问题讨论】:

  • 这是 Python 2 吗? Python 可以使用宽或窄的 Unicode 支持来构建;你可能有一个 UCS-2 版本而不是 UCS-4,这会影响你可以用正则表达式做什么。
  • 请给我们一个输入样本。
  • 我能够重现您的问题,而且我还看到 UCS-2 构建在尝试编译表达式时会引发异常,所以这不是这里的问题。
  • u'\u1f300' 应该是 u'\U0001f300'。第一个是'\u1f30''0'

标签: python regex unicode emoji tweets


【解决方案1】:

您没有对非 BMP unicode 点使用正确的表示法;你想使用\U0001FFFF,一个大写 U和8位数字:

myre = re.compile(u'['
    u'\U0001F300-\U0001F5FF'
    u'\U0001F600-\U0001F64F'
    u'\U0001F680-\U0001F6FF'
    u'\u2600-\u26FF\u2700-\u27BF]+', 
    re.UNICODE)

这可以简化为:

myre = re.compile(u'['
    u'\U0001F300-\U0001F64F'
    u'\U0001F680-\U0001F6FF'
    u'\u2600-\u26FF\u2700-\u27BF]+', 
    re.UNICODE)

因为你的前两个范围是相邻的。

您的版本正在指定(为便于阅读添加了空格):

[\u1F30 0-\u1F5F F\u1F60 0-\u1F64 F\u1F68 0-\u1F6F F \u2600-\u26FF\u2700-\u27BF]+

这是因为 \uxxxx 转义序列总是只需要 4 个十六进制数字,而不是 5 个。

其中最大的范围是 0-\u1F6F(从数字 0),它涵盖了 Unicode 标准的非常大的范围

如果您使用 UCS-4 范围的 Python 可执行文件,则更正后的表达式有效:

>>> import re
>>> myre = re.compile(u'['
...     u'\U0001F300-\U0001F64F'
...     u'\U0001F680-\U0001F6FF'
...     u'\u2600-\u26FF\u2700-\u27BF]+', 
...     re.UNICODE)
>>> myre.sub('', u'Some example text with a sleepy face: \U0001f62a')
u'Some example text with a sleepy face: '

UCS-2 等效项是:

myre = re.compile(u'('
    u'\ud83c[\udf00-\udfff]|'
    u'\ud83d[\udc00-\ude4f\ude80-\udeff]|'
    u'[\u2600-\u26FF\u2700-\u27BF])+', 
    re.UNICODE)

您可以使用异常处理程序将两者结合到您的脚本中:

try:
    # Wide UCS-4 build
    myre = re.compile(u'['
        u'\U0001F300-\U0001F64F'
        u'\U0001F680-\U0001F6FF'
        u'\u2600-\u26FF\u2700-\u27BF]+', 
        re.UNICODE)
except re.error:
    # Narrow UCS-2 build
    myre = re.compile(u'('
        u'\ud83c[\udf00-\udfff]|'
        u'\ud83d[\udc00-\ude4f\ude80-\udeff]|'
        u'[\u2600-\u26FF\u2700-\u27BF])+', 
        re.UNICODE)

当然,正则表达式已经过时了,因为它不包括在较新的 Unicode 版本中定义的表情符号;它似乎涵盖了 Unicode 8.0 之前定义的表情符号(因为 U+1F91D HANDSHAKE 是在 Unicode 9.0 中添加的)。

如果您需要更新的正则表达式,请从a package that is actively trying to keep up-to-date on Emoji 获取一个;它特别支持生成这样的正则表达式:

import emoji

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

该软件包目前是 Unicode 11.0 的最新版本,并且具有可快速更新到未来版本的基础架构。您的项目所要做的就是在有新版本时进行升级。

【讨论】:

  • 正是我在上面评论的内容,但我在 Python 2 窄版本上得到了sre_constants.error: bad character range
  • @MarkTolonen:是的,您只能在广泛的构建中使用它,请参阅Python, convert 4-byte char to avoid MySQL error "Incorrect string value:" 了解一种方法(您必须改为匹配 UTF-16 代理对)。
  • @MarkTolonen:添加了 UCS-2 版本。
  • 这就是我使用 Python 3.3+ 的原因 :)
  • @abc:BMP 使用高达 0xFFFF 的代码点。那是四位数。 BMP 之外的任何内容都使用 more 四个十六进制数字,因此您不能使用 \uhhhh 4 位语法,您需要使用 \Uhhhhhhhh 8 位语法。
猜你喜欢
  • 2018-05-09
  • 2015-09-25
  • 2017-01-14
  • 2014-08-30
  • 1970-01-01
  • 2015-03-01
  • 2021-08-16
  • 2012-02-13
  • 2021-11-27
相关资源
最近更新 更多