pt regex remove caracteres especiais

0

Eu tenho um arquivo com várias strings que vêm de um texto formatado em HTML, então eles têm algumas seqüências HTML que não parecem boas em uma interface de console. Aqui está um exemplo:

Text1™
[Text®2]
Text:3

A coisa que estou tentando é remover tudo entre & e; então o texto é legível novamente, como o seguinte:

Text1
Text2
Text3

Na verdade, estou tentando usar sed para remover os caracteres extras:

sed 's#&*;##g' <file>

O problema é que apenas remove o; das cadeias de texto.

A pergunta é, então, como a expressão do regex deve ser codificada para remover a cadeia extra: & # [1-9] +;

    
por Peter 11.01.2013 / 13:25

2 respostas

1

Seu regexp

sed 's#&*;##g' <file>

não faz o que você acha que faz. O caractere * é um multiplicador que diz que o caractere precedente é repetido 0 ou mais vezes. O caractere anterior é & , portanto, isso corresponderia, por exemplo, &&&; e ; ( & é escrito 0 vezes antes de ; ! Isto é o que está correspondendo em seus casos de teste) mas não o que você quer neste caso.

Você precisa especificar " qualquer caractere" antes do multiplicador, que é representado por um único ponto, . .

$ echo 'Text&#58;3' | sed 's#&.*;##g'
Text3

Esse foi o primeiro problema. O segundo é o conceito de correspondência "gananciosa": sed verá o primeiro & e tentará combinar a maior sequência possível. Se você tiver várias entidades HTML em uma única linha, isso seria um problema, pois:

$ echo 'Text&#58;3 and some more text &aring; and end' | sed 's#&.*;##g'
Text and end

Se você quiser ver uma correção no contexto sed , poderá procurar o caractere final da entidade correspondendo qualquer número de " não ; " antes de um fechamento ; fazendo:

$ echo 'Text&#58;3 and some more text &aring; and end' | sed 's#&[^;]*;##g'
Text3 and some more text  and end

Você ainda terá problemas com o uso legítimo do sinal de e comercial ( & ) no texto (bem, &amp; é o verdadeiro uso "legítimo", mas o mundo real nem sempre é tão parsável quanto o ideal ) e combinando muito, mas isso explica porque o sed está se comportando da maneira como funciona.

    
por 11.01.2013 / 13:53
0

Não é melhor substituir os códigos pelos caracteres reais?

echo 'Text1&#8482;
&#91;Text&#174;2&#93;
Text&#58;3' | perl -C -pe 's/&#([^;]*)/chr$1/eg'

Saída:

Text1™;
[;Text®;2];
Text:;3
    
por 11.01.2013 / 13:37