如何在文本文件中查找并移除表情符号?

7

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

我能否轻松地使用bash或perl完成此操作?还是应该使用其他语言?

编辑:感谢Cyrus和Barmar指引我朝这个问题前进。但是,它并没有告诉我如何仅从文本文件中删除表情符号。他们使用以下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 不会返回任何内容。

有人知道如何从文本中删除那些特定的字符吗?

注意:我知道这个问题,但我的文本文件没有任何格式。 表情符号与其余文本混合在一起。


欢迎来到Stack Overflow。SO是一个专业和爱好者程序员的问答网站。我们的目标是,您需要在提问中至少添加一些自己编写的代码,展示您为解决问题所做的研究工作。 - Cyrus
此外,https://stackoverflow.com/questions/45783627/regex-to-delete-emojis-from-string 可能会有所帮助。 - Zak
可能相关:https://dev59.com/lafja4cB1Zd3GeqPzrKd - Nick Reed
@Cyrus编辑了问题并提供了更多信息,是否可以重新打开?除非它再次重复,否则我只是在Google上真的很差。 - Whitehot
1
基于编辑后的问题,我投票重新开放这个问题,以便有人可以提供一个解决方案来删除表情符号而不是找到它们。 - GMB
4个回答

13

2020 更新:Perl v5.32 使用 Unicode 13 并支持处理表情符号的 多个属性。您可以简单地使用 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 ...

旧版 Perl 的字符类

在 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提到了一种表情符号属性,但它没有列在perluniprop中。如果有这样的属性,您可以简化该属性并删除带有该属性的任何内容:

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

Emoticon属性,但它并不涵盖您的字符类。我还没有查看它是否与UTS#51中的Emoji属性相同。

用户定义的Unicode属性

您可以通过定义一个以InIs开头并后跟您选择的属性名称的子例程来创建自己的属性。该子例程返回一个潜在的多行字符串,其中每行都是单个十六进制代码数字或由水平空格分隔的两个十六进制代码数字。然后,所有这些字符都属于您的属性。

这里是将相同字符类作为用户定义的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表示要加载的模块):

现在,您可以在一行代码中使用它(-I. 将当前目录添加到模块搜索路径中,-M 表示要加载的模块):
$ perl -CS -I. -MIsEmoji -pe 's/\p{IsEmoji}//g' file1 file2

除此之外,在您的单行代码中,您将被限制使用长字符类。


2
注意:\p{Emoji} 过滤器也会过滤数字([0-9])!因为有数字表情符号,所以这意味着纯数字也会被归类到该类别中。–.– - anon

2
下面的bash脚本是一个示例,展示了如何使用sed去除表情符号。这需要bash 4.2或更高版本来支持`\U`(所以在macOS上,您需要`brew install bash`)。
表情符号范围取自Suhail Gupta的答案,并重新格式化为bash兼容。
我们使用它从`Deliverfile`中去除表情符号,用于Fastlane,以便上传到苹果应用商店,在许多字段中不允许使用表情符号。
#!/usr/bin/env bash
# ^ use bash from path, not from /bin/bash https://dev59.com/0GEi5IYBdhLWcg3wIJJH#21613044
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)也被删除了。如果添加变量选择器 U+FE0F,它将在支持的系统上变成带有表情符号样式的✈️。根据您的情况,您可能需要调整正则表达式以仅删除彩色表情符号字符。

1
嗨,感谢您的回答,它可以正常工作!只是想补充一下,这个网站:https://www.rapidtables.com/convert/number/ascii-to-hex.html可以将表情符号转换为十六进制,因此如果将来有人想要将新的表情符号添加到列表中,就可以使用它。 - Luis Tiago Flores Cristóvão

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)

0

这个 Perl 脚本并没有删除任何东西,它只是打印出一个笑脸。 - anon

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