Perl: глобальная подстановка в строке с разделителями тегов - PullRequest
1 голос
/ 01 августа 2010

В моем предыдущем посте теги были частично удалены, поэтому снова здесь:

Моя цель - заменить все экземпляры трейлинга на трейлинг + в квадратных скобках. Предположим, что строка для замены выглядит следующим образом:

<h> aa- aa- </h> <h> ba- ba- </h> 

и впоследствии должен выглядеть как

<h> aa+ aa+ </h> <h> ba+ ba+ </h>.

Сначала я попробовал это выражение:

s/<h>(.*?)-(.*?)<\/h>/<h>$1+$2<\/h>/g;

, который дал этот вывод:

<h> aa+ aa- </h> <h> ba+ ba- </h>.

Опция g приводит к более чем одной замене на строку, но только для первого экземпляра в скобках тега (и только если в обеих круглых скобках содержится знак вопроса).

Чтобы сузить проблему, я затем попытался добиться замены, не обращая внимания на теги. Выражение

s/(.*?)-(.*?)/$1+$2/g;

действительно приводит к желаемому результату

<h> aa+ aa+ </h> <h> ba+ ba+ </h>.

Это, конечно, заменит скобки за пределами тега.

Так в чем же проблема с моим первым выражением и как мне достичь цели полной замены в скобках тегов?

Ответы [ 2 ]

0 голосов
/ 01 августа 2010

Разделите операции выбора тега и замены:

$str = '<h> aa- aa- </h> <h> ba- ba- </h>';
while ( $str =~ m!<h>.*?-.*?</h>! ) {
    substr( $str, $-[0], $+[0] - $-[0] ) =~ y/-/+/;
}
print $str, "\n";

(массивы @- и @+ предоставляют информацию о смещении о последнем успешном совпадении.)

В качестве альтернативы:

sub fixup_h_tag {
    my $tag = shift;
    $tag =~ y/-/+/;
    $tag
}
$str = '<h> aa- aa- </h> <h> ba- ba- </h>';
$str =~ s{ (<h>.*?</h>) }{ fixup_h_tag("$1") }gxe;
print $str, "\n";

Обратите внимание, что если ваш язык разметки тегов допускает комментарии или строки в кавычках (которые могут содержать или не быть тегами), или необязательные пробелы или атрибуты в теге h, регулярные выражения не будут легко предоставлятьнадежное решение.

0 голосов
/ 01 августа 2010

1) опция g работает для целых тегов с регулярным выражением

2) используйте его дважды или пока не изменится

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