Como remover strings russas e arábicas de um arquivo de texto

3

Problema: Eu tenho arquivo de texto com aproximadamente 1 milhão de linhas, cada linha consiste em várias palavras Algumas linhas contêm palavras em russo ou árabe (vamos chamá-las de "linhas ruins"), quero remover apenas essas linhas ruins. Os outros são "boas linhas".

Condições:

  • Existem caracteres não-ascii em algumas linhas boas, portanto remover apenas todos os não-ascii não resolve o problema.
  • Cada linha é completamente ruim ou boa, então isso realmente torna as coisas um pouco mais fáceis.

Então, a solução que me veio à mente é apenas:

sort file.txt > sorted.txt

Qualquer coisa que comece com russo ou árabe será listada no final. E então eu vou verificar manualmente a linha que eles começam e depois fazer

head -n X sorted.txt > clean.txt

para se livrar deles. Existe uma maneira mais elegante de fazer isso? Quais outras ferramentas Unix podem ser usadas para realizar essa tarefa.

Exemplo de entrada:

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

Saída desejada:

kedi
cat
candy
şeker
çağrı
resumé
    
por Gani Simsek 21.10.2014 / 18:10

1 resposta

2

Isso deve funcionar pelo menos para o seu exemplo:

$ 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é

A idéia básica é usar o \p para definir um conjunto de pontos de código, neste caso, arábico ou cirílico e, se uma linha corresponder, ela não será impressa. Infelizmente, eu mesmo não entendo os detalhes, isso foi fornecido por @tchrist em bate-papo . Eu sugiro que você leia a descrição dele lá. Eu não tenho tempo para decifrar o regex agora, mas vou adicionar uma explicação assim que tiver a chance de entendê-lo eu mesmo. Dada a fonte, estou assumindo que é mais completa e mais segura do que a minha versão minimalista abaixo.

Uma versão simplificada disso que está dentro do meu próprio entendimento é

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

Isso imprimirá todas as linhas que não contiverem caracteres arábicos ou cirílicos somente . O -CS informa perl que STDIN, STDOUT e STDERR são todos unicode. O -ne significa "leia cada linha de entrada e aplique o script fornecido por -e . A /foo/ || bar significa do bar se a linha não corresponder a foo . Nesse caso, imprima se a linha não corresponder qualquer caractere árabe ou cirílico.

Finalmente, o \p{} é (de man perluniprops ):

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

Isso permite que você combine uma série de caracteres, como árabe ou cirílico, ou praticamente qualquer outra coisa em que você possa pensar. Portanto, a classe caracteres [\p{foo}] corresponderá a qualquer caractere do script foo . Portanto, [\p{Arabic}\p{Cyrillic}] corresponderá a qualquer caractere dos dois scripts.

    
por 21.10.2014 / 19:12