LINUX.ORG.RU

Найти все теги, в которых нет заданной подстроки


0

1

Необходимо при помощи regexp найти все последовательности «<a>текст</a>», причём если в тексте встретится строка «111» (например «<a>пролдж111фыва</a>»), то данный тег не должен соответствовать шаблону.
У меня максимум, что получилось, это такой шаблон: «/<a>[^4]*<\/a>/», но он бракует только строки с символом «4» между тегами. А мне необходимо браковать строку из более одного символа. Как?

В чём планируется применять это регулярное выражение? Не проще ли разбить фильтрацию на 2 этапа (что-то вроде «print if m#<a>([^<]*)</a># and $1 !~ /forbidden/»)?

AITap ★★★★★
()
Ответ на: комментарий от AITap

Вобще, частенько была такая ситуация. Я её обходил более штатными способами, но всё же охота, наконец, решить задачу regexp'ом.
Идея такая: я хочу выбрать полностью тег <a></a> с содержимым. Но в тексте у меня таких тегов много. Одно из условий: друг в друга теги не вкладываются. Если я применю шаблон «<a>.*</a>», то он мне выбирает только один вариант: текст от самого первого в тексте тега <a> до самого последнего </a>. А вот как по шаблону выбрать весь список тегов <a></a>?

С тремя единицами я привёл пример для простоты. Потом хотел на их место вставить «a>».

abr_linux
() автор топика
Ответ на: комментарий от abr_linux

Костыль. Тебе нужен «нежадный» (non-greedy) квантификатор *.

Кажется, в sed/grep нежадный * выглядит как {}. Для других случаев читай маны @ гугли.

schizoid ★★★
()
$ cat test.txt
no match
<a>match ok</a>
garbage fake trash
<a>none 111 sigh</a>
<a>yao ok</a>
bad line
$ grep '<a>.*<\/a>' test.txt | egrep -v '.*1+.*'
<a>match ok</a>
<a>yao ok</a>
$

Так не пойдёт?

Само собой вместо «1+» надо подставить требуемый шаблон.

OldFatMan
()

rain@acnote:~$ echo -e '<a>test</a>\n<a>test123test</a>\n<a>testtest</a>\n123' | grep -vP '(?=\<a\>).*123.*(?<=\<\/a\>)'
<a>test</a>
<a>testtest</a>
123

YAR ★★★★★
()
Ответ на: комментарий от schizoid

У меня обычно бывает полдня мучаюсь безрезультатно, только напишу в порыве отчаянья на форум, как сразу идеи лезут.
Нашёл два способа. Один из них, правда, требует щё подумать.
1. «<a>.*?</a>» - нашёл на педивикии. В самом деле, нежадный квантификатор помог. Хотя, тут возникает сложность, если мне нужно задать доп. шаблон для содержимого тега.
2. «<a>[^(?:a>)]*<\/a>» - оказалось, если заменить [^4] на [^(?:a>)], всё работает так, как и надо. И даже можно дополнительный шаблон задавать для текста внутри тега :)

Спасибо всем за помощь :)

abr_linux
() автор топика
Ответ на: комментарий от abr_linux

Одно из условий: друг в друга теги не вкладываются.

Разве такой regexp не удовлетворяет этому требованию?
/<a>[^<]*</a>/

AITap ★★★★★
()
Ответ на: комментарий от AITap

По идее, удовлетворяет. Но я сделал «a>», потому что надо, чтобы только теги <a> друг в друга не вкладывались

abr_linux
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.