【问题标题】:How do I find and remove emojis in a text file?如何在文本文件中查找和删除表情符号?
【发布时间】:2020-02-13 17:32:04
【问题描述】:

我正在尝试从我主要使用 sed 和一些 perl 命令解析的文本文件中删除所有表情符号,并且最好将它们存储在单独的文件中,但这不是必需的。

我可以用 bash 或 perl 轻松做到这一点吗?还是应该使用其他语言?

编辑:感谢 Cyrus 和 Barmar 为我指明了正确的方向,即 this question。但是,它并没有告诉我如何从文本文件中删除表情符号。他们使用 bash 行:

grep -P "[\x{1f300}-\x{1f5ff}\x{1f900}-\x{1f9ff}\x{1f600}-\x{1f64f}\x{1f680}-\x{1f6ff}\x{2600}-\x{26ff}\x{2700}-\x{27bf}\x{1f1e6}-\x{1f1ff}\x{1f191}-\x{1f251}\x{1f004}\x{1f0cf}\x{1f170}-\x{1f171}\x{1f17e}-\x{1f17f}\x{1f18e}\x{3030}\x{2b50}\x{2b55}\x{2934}-\x{2935}\x{2b05}-\x{2b07}\x{2b1b}-\x{2b1c}\x{3297}\x{3299}\x{303d}\x{00a9}\x{00ae}\x{2122}\x{23f3}\x{24c2}\x{23e9}-\x{23ef}\x{25b6}\x{23f8}-\x{23fa}]"  myflie.txt | more

这让我得到了所有包含表情符号的

grep -Pv 将从输入中删除这些行,

grep -Po 将只返回表情符号,

grep -Pov 不返回任何内容。

有谁知道如何从文本中删除这些特定字符?

注意:我知道this question,但我的文本文件根本没有格式化。表情符号与文本的其余部分混合在一起。

【问题讨论】:

  • 欢迎来到 Stack Overflow。 SO 是一个面向专业和爱好者程序员的问答网站。目标是您将一些自己的代码添加到您的问题中,以至少显示您为解决这个问题所做的研究工作。
  • 也 --> stackoverflow.com/questions/45783627/… 可能会有所帮助。
  • @Cyrus 用更多信息编辑了问题,是否可以重新打开?除非它再次重复,而且我在 Google 上真的很糟糕
  • 基于已编辑的问题,我投票决定重新打开此问题,以便有人可以提供解决方案来删除表情符号而不是 grepping 它们。

标签: emoji


【解决方案1】:

2020 更新:Perl v5.32 使用 Unicode 13 并支持处理表情符号的 several properties。您可以简单地使用Emoji 属性:

#!perl
use v5.32;
use utf8;
use open qw(:std :utf8);

while( <<>> ) {  # double diamond (from v5.26) 
    s/\p{Emoji}//g;
    print;
    }

作为单行,这变成:

% perl -CS -pe 's/\p{Emoji}//g' file1 file2 ...

旧 Perls 的字符类

在 Perl 中,删除表情符号就是这么简单。从本质上讲,这与您在 sed 中所做的非常接近。更新任务的模式和其他详细信息:

#!perl
use utf8;
use open qw(:std :utf8);

my $pattern = "[\x{1f300}-\x{1f5ff}\x{1f900}-\x{1f9ff}\x{1f600}-\x{1f64f}\x{1f680}-\x{1f6ff}\x{2600}-\x{26ff}\x{2700}-\x{27bf}\x{1f1e6}-\x{1f1ff}\x{1f191}-\x{1f251}\x{1f004}\x{1f0cf}\x{1f170}-\x{1f171}\x{1f17e}-\x{1f17f}\x{1f18e}\x{3030}\x{2b50}\x{2b55}\x{2934}-\x{2935}\x{2b05}-\x{2b07}\x{2b1b}-\x{2b1c}\x{3297}\x{3299}\x{303d}\x{00a9}\x{00ae}\x{2122}\x{23f3}\x{24c2}\x{23e9}-\x{23ef}\x{25b6}\x{23f8}-\x{23fa}]";

while( <DATA> ) {  # use <> to read from command line
    s/$pattern//g;
    print;
    }

__DATA__
Emoji at end ?
? Emoji at beginning
Emoji ? in middle

UTS #51 mentions an Emoji property,但未在perluniprop 中列出。如果有这样的事情,您会简化删除具有该属性的任何内容:

while( <DATA> ) {
    s/\p{Emoji}//g;
    print;
    }

Emoticon 属性,但这不包括您的角色类。我还没有查看它是否与 UTS #51 中的 Emoji 属性相同。

用户定义的 Unicode 属性

您可以通过定义一个以InIs 开头的子例程,后跟您选择的属性名称来生成your own properties。该子例程返回一个潜在的多行字符串,其中每一行是单个十六进制代码数字或由水平空格分隔的两个十六进制代码数字。所有这些中的任何角色都是您财产的一部分。

这是与用户定义的 Unicode 属性相同的字符类。请注意,我使用squiggly heredoc,主要是因为我可以使用前导空格在本地编写程序,因此我可以直接粘贴到 StackOverflow 中。 IsEmoji 中的行不能有前导空格,但是缩进的heredoc 会处理这一点:

#!perl
use v5.26; # for indented heredoc
use utf8;
use open qw(:std :utf8);

while( <DATA> ) {  # use <> to read from command line
    s/\p{IsEmoji}//g;
    print;
    }

sub IsEmoji { <<~"HERE";
1f300 1f5ff
1f900 1f9ff
1f600 1f64f
1f680 1f6ff
2600 26ff
2700 27bf
1f1e6 1f1ff
1f191 1f251
1f004 1f0cf
1f170 1f171
1f17e 1f17f
1f18e
3030
2b50
2b55
2934 2935
2b05 2b07
2b1b 2b1c
3297
3299
303d
00a9
00ae
2122
23f3
24c2
23e9 23ef
25b6
23f8 23fa
HERE
}

__DATA__
Emoji at end ?
? Emoji at beginning
Emoji ? in middle

你可以把它放在一个模块中:

# IsEmoji.pm
sub IsMyEmoji { <<~"HERE";
1f300 1f5ff
...  # all that other stuff too
23f8 23fa
HERE
}

1;

现在您可以在单行中使用它(-I. 将当前目录添加到模块搜索路径,-M 表示要加载的模块):

$ perl -CS -I. -MIsEmoji -pe 's/\p{IsEmoji}//g' file1 file2

除此之外,您还被单行中的长字符类所困扰。

【讨论】:

    【解决方案2】:

    试试这个:

    第一种方法

    import emoji
    import re
    
    test_list=[]
    
    ## 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)
    
    ## Executing function
    extract_emojis(test_list)
    

    第二种方法

    import re
    import sys
    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)
    if __name__ == '__main__':
    
    text = open(sys.argv[1]).read()
    text = remove_emoji(text)
    print(text)
    

    【讨论】:

      【解决方案3】:

      以下 bash 脚本是如何使用 sed 去除表情符号的一个示例。这需要 bash 4.2 或更高版本才能支持\U(所以在 macOS 上,您需要brew install bash)。

      表情符号范围取自 Suhail Gupta's answer 并重新格式化以使其与 bash 兼容。

      我们正在使用它从Deliverfile 中删除表情符号,以便与Fastlane 一起使用,以便上传到Apple App Store,这在许多字段中不允许表情符号。

      #!/usr/bin/env bash
      # ^ use bash from path, not from /bin/bash https://stackoverflow.com/a/21613044/1836776
      emoji="\U1f300-\U1f5ff\U1f900-\U1f9ff\U1f600-\U1f64f\U1f680-\U1f6ff\U2600-\U26ff\U2700-\U27bf\U1f1e6-\U1f1ff\U1f191-\U1f251\U1f004\U1f0cf\U1f170-\U1f171\U1f17e-\U1f17f\U1f18e\U3030\U2b50\U2b55\U2934-\U2935\U2b05-\U2b07\U2b1b-\U2b1c\U3297\U3299\U303d\U00a9\U00ae\U2122\U23f3\U24c2\U23e9-\U23ef\U25b6\U23f8-\U23fa"
      sample="This ? is ⭐ a ? line ? of ? emoji ✈"
      echo $sample
      echo $sample | LC_ALL=UTF-8 sed -e "s/[$(printf $emoji)]//g"
      

      这给出了结果:

      This ? is ⭐ a ? line ? of ? emoji ✈
      This  is  a  line  of  emoji
      

      请注意 ✈ 字符 (U+2708) 是如何被剥离的,即使它看起来不像彩色表情符号。添加variation selector U+FE0F 将在支持它的系统上将其变成表情符号风格的✈️。根据您的具体情况,您可能需要调整您的正则表达式以仅去除彩色表情符号字符。

      【讨论】:

      • 您好,感谢您的回答,它工作正常!只需添加此站点:rapidtables.com/convert/number/ascii-to-hex.html 可以将表情符号转换为十六进制,因此如果将来有人想在列表中添加一些新的表情符号,它可以。
      【解决方案4】:

      您可以删除整个表情符号表 (https://apps.timwhitlock.info/emoji/tables/unicode)

      perl -e '$t=pack("H*", "f09f9889"); print$t,$/; $t=~s/\xF0\x9F[\x98-\x99][\x81-\x8F]//; print$t,$/'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-12-15
        • 2023-02-02
        • 2017-10-09
        • 2017-08-23
        • 1970-01-01
        • 2019-01-17
        • 2021-06-08
        • 1970-01-01
        相关资源
        最近更新 更多