如何从文本文件中删除俄语和阿拉伯语字符串

如何从文本文件中删除俄语和阿拉伯语字符串

问题: 我有大约 1M 行的文本文件,每行由多个单词组成,有些行包含俄语或阿拉伯语单词(我们称它们为“坏行”),我只想删除这些坏行。其他都是“好线路”。

状况:

  • 一些好行中存在非 ASCII 字符,因此仅删除所有非 ASCII 字符并不能解决问题。
  • 每条线要么完全坏,要么完全好,所以这实际上让事情变得更容易一些。

所以我想到的解决方案就是:

sort file.txt > sorted.txt

任何以俄语或阿拉伯语开头的内容都将列在最后。然后我会手动检查他们开始的行,然后执行

head -n X sorted.txt > clean.txt

摆脱他们。有没有更优雅的方法来做到这一点?还有什么其他 Unix 工具可以用来完成这个任务。

输入示例:

kedi
cat
кошка
القط
candy
şeker
конфеты
كاندي
çağrı
resumé

期望的输出:

kedi
cat
candy
şeker
çağrı
resumé

答案1

这至少应该适用于您的示例:

$ perl -CS -Mutf8 -lne 's{ 
            (?= [\p{Arabic}\p{Cyrillic}] ) 
            [\p{Arabic}\p{Cyrillic}\p{Common}\p{Inherited}] + 
            (?<= [\p{Arabic}\p{Cyrillic}] ) }{}xg || print' < file

kedi
cat
candy
şeker
çağrı
resumé

基本思想是使用\p定义一组代码点,在本例中是阿拉伯语或西里尔语,如果一行匹配,则不会打印。不幸的是,我自己不明白细节,这是由@tchrist聊天。我建议你在那里阅读他的描述。我现在没有时间破译正则表达式,但一旦我有机会自己理解它,我会立即添加解释。鉴于来源,我假设它比下面我的极简版本更完整、更安全。


我自己理解的一个简化版本是

$ perl  -CS -ne '/[\p{Arabic}\p{Cyrillic}]+/ || print' < file 

这将打印不包含任何阿拉伯或西里尔字符的所有行仅有的。说明 STDIN、STDOUT 和 STDERR 都是 unicode -CSperl-ne含义是“读取每个输入行并应用 给定的脚本-e。如果该行与 不匹配,则/foo/ || bar表示执行操作。在这种情况下,如果该行与任何阿拉伯或西里尔字符不匹配,则打印。barfoo

最后,\p{}是(来自man perluniprops):

   The Perl regular expression "\p{}" and "\P{}" constructs give access to
   most of the Unicode character properties. 

这允许您匹配一系列字符,例如阿拉伯语或西里尔语或几乎任何您能想到的其他字符。因此,字符类 [\p{foo}]将匹配脚本的任何字符foo。因此,[\p{Arabic}\p{Cyrillic}]将匹配两个脚本的任何字符。

相关内容