sed regex удалить специальные символы

sed regex удалить специальные символы

У меня есть файл с несколькими строками, которые берутся из текста в формате HTML, поэтому в них есть некоторые последовательности HTML, которые не очень хорошо выглядят в интерфейсе консоли. Вот пример:

Text1™
[Text®2]
Text:3

Я пытаюсь удалить все между & и ;, чтобы текст снова стал читаемым, как показано ниже:

Text1
Text2
Text3

На самом деле я пытаюсь использовать sed, чтобы удалить лишние символы:

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

Проблема в том, что он удаляет только ; из текстовых строк.

Тогда возникает вопрос, как следует закодировать выражение регулярного выражения, чтобы удалить лишнюю цепочку:&#[1-9]+;

решение1

Ваше регулярное выражение

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

не делает то, что вы думаете. Символ *является множителем, который говорит, что предыдущий символ повторяется 0 или более раз. Предыдущий символ — &, поэтому это будет соответствовать, например, &&&;и ;( &записано 0 раз до ;! Это то, что соответствует в ваших тестовых случаях), но не то, что вы хотите в этом случае.

Вам необходимо указать "любойсимвол» перед множителем, который представлен одной точкой, ..

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

Это была первая проблема. Вторая — это концепция так называемого «жадного» сопоставления: sedувидит первую &и попытается сопоставить самую большую строку, какую только сможет. Если у вас несколько HTML-сущностей на одной строке, это будет проблемой, поскольку:

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

Если вы хотите увидеть исправление в sedконтексте, вы можете поискать конечный символ сущности, сопоставив любое количество "нет ;" перед закрытием, ;выполнив:

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

У вас по-прежнему будут проблемы с допустимым использованием знака амперсанда ( &) в тексте (ну, &amp;это действительно «допустимое» использование, но реальный мир не всегда так же поддается анализу, как идеальный) и слишком большим количеством соответствий, но это объясняет, почему sedон ведет себя именно так.

решение2

Не лучше ли заменить коды реальными символами?

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

Выход:

Text1™;
[;Text®;2];
Text:;3

Связанный контент