Глобальная замена Perl с взглядом вперед и взглядом назад?

Я пытаюсь выполнить глобальную замену в Perl в строке на основе определенного шаблона, НЕ совпадающего до или после определенного совпадения. По сути, у меня есть тег xml, и я хочу сохранить его, если совпадение происходит в пределах десяти символов до или после тега, но удалить тег xml, если нет.

Итак, если у меня есть строка, содержащая:

foo something<xml tag>bar<\xml tag> something

Подстановки не произойдет, но если строка

something <xml tag>bar<\xml tag> something

он будет заменен на:

something bar something

Что я пробовал:

$string =~ s/(?<!foo.{0,10})<xml tag>(bar)<\/xml tag> |<xml tag>(bar)<\/xml tag>(?!.{0,10}foo)/$1/g;

Но я получил эту ошибку:

Variable length lookbehind not implemented in regex

Я не совсем уверен, как это сделать. Помощь?


person aa762    schedule 30.10.2013    source источник
comment
Поиск позади в регулярном выражении должен быть фиксированной длины: -r" title="какая техническая причина для утверждения lookbehind должна быть фиксированной длины в r"> stackoverflow.com/questions/3796436/   -  person Martyn    schedule 30.10.2013


Ответы (2)


Из perlretut:

Предварительный просмотр "(?=regexp)" может соответствовать произвольным регулярным выражениям, но просмотр назад "(?‹=fixed-regexp)" работает только для регулярных выражений фиксированной ширины, т. е. фиксированного количества символов в длину. Таким образом, "(?‹=(ab|bc))" подходит, а "(?‹=(ab)*)" - нет.

Поэтому, если слово (слова) имеет фиксированную длину до <xml tag>bar<\xml tag>, вы должны использовать его, иначе вы можете использовать, например, более одного регулярного выражения.

person edem    schedule 30.10.2013

Один из способов с использованием флага e:

while (<DATA>) {
    s/((.{0,13})<xml\ tag>([^<]*)<\/xml\ tag>)(?!.{0,10}foo)/
    index($2,'foo') > -1 ? "$1" : "$2$3"/xe;
    print $_; 
}

__DATA__
foo something<xml tag>bar</xml tag> something
something <xml tag>bar</xml tag> something

Производит:

foo something<xml tag>bar</xml tag> something
something bar something
person perreal    schedule 30.10.2013