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

Text1™
[Text®2]
Text:3

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

Text1
Text2
Text3

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

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

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

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

2 ответа2

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 , вы можете найти конечный символ сущности, сопоставив любое число « not ; » перед закрытием ; при выполнении:

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

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

0

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

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

Выход:

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .