Странный результат для Perl Regexp - конец строки привязки и ungreedy сразу - PullRequest
0 голосов
/ 10 августа 2010

У меня есть очень простая замена:

my $s = "<a>test</a> <a>test</a>";
$s =~ s{ <a> .+? </a> $ }{WHAT}x;

print "$s\n";

, которая печатает:

WHAT

Но я ожидал:

<a>test</a> WHAT

Что я неправильно понимаю"конец строки привязки" во взаимодействии с опцией ungreedy?

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

Просто сначала найдите <a>, а затем найдите </a>$.Первая блокировка положительна, шаблон соответствует.

Правильный шаблон должен быть примерно таким:

$s =~ s{ <a> (?! .* <a> ) .* </a> }{WHAT}x;

, что дает мне правильно

<a>test</a> WHAT

, потому что сейчас Я действительно попросил регулярное выражение для last <a>.

Я думаю, что это менее эффективно [^<]+, но более гибко.

Ответы [ 2 ]

5 голосов
/ 10 августа 2010

Это одна из причин, по которой вы не используете регулярные выражения для соответствия HTML.Попробуйте вместо этого использовать парсер.См. Этот вопрос и его ответы по другим причинам, не использующим регулярное выражение, и этот вопрос и его ответы для примеров того, как использовать анализатор HTML.

4 голосов
/ 10 августа 2010

Нежадный модификатор (и регулярные выражения в целом) работает слева направо, поэтому, по сути, здесь происходит то, что он пытается найти самую короткую строку, которая соответствует первой <a> до следующей </a>, который находится в конце строки.

Это делает то, что вы ожидаете:

my $s="<a>test</a> <a>test</a>";
$s =~ s#<a>[^<>]+</a>$#WHAT#;

print "$s\n";

Какую проблему вы пытаетесь решить?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...