Неинициализированная обратная ссылка в замещении - PullRequest
2 голосов
/ 02 августа 2011

Предполагая, что я должен выполнить эту замену, используя одну подстановку, какой метод предпочтительнее избежать этой ошибки:

Use of uninitialized value $2 in concatenation (.) or string at -e line 1.

С этим кодом Perl:

perl -e 'use strict;use warnings;my $str="a";$str=~s/(a)|(b)/$1foo$2/gsmo;'

Цельздесь нужно либо напечатать «afoo», либо «foob» в зависимости от того, что содержит $str.

Я могу использовать no warnings;, но потом я боюсь, что пропущу другие «настоящие» предупреждения.Я также знаю, что использование одного паттерна делает это запутанным, но мой реальный паттерн намного сложнее.

Если вам интересно, фактические замены ближе к:

#!perl
my $search = q~(document\.domain.*?</script>)|(</head>)~;
my $search_re = qr/$search/smo;
my $replace = q("$1
<script src=\"/library.js\"></script>
$2");
while (<*.tmpl>) {
  my $str = fead_file($_);
  $str =~ s/$search_re/$replace/gee;
}

Но еще сложнее, в основномПриведенный выше код просто читает из БД, чтобы найти и заменить, а затем выполняет их в шаблон.Запуск этого сценария дважды с каждым коммитом привел бы к чрезмерным накладным расходам, по-видимому ... так говорится в них ...

Ответы [ 4 ]

2 голосов
/ 02 августа 2011

Вы можете:

my $replace = q("@{[$1||'']}
<script src=\"/library.js\"></script>
@{[$2||'']}");

(используя // вместо || на 5.10 +)

1 голос
/ 02 августа 2011

До сих пор работает с / г:

s/(a)|(b)/ ($1 // '') . 'foo' . ($2 // '') /ge
0 голосов
/ 02 августа 2011

Аналогично решению ikegami: если вы хотите сохранить замену в переменной, вы можете вызвать ссылку на код в s///e, передав ей записи.

#!perl
my $search = q~(document\.domain.*?</script>)|(</head>)~;
my $search_re = qr/$search/smo;
my $replace = sub {
    my $one = shift || '';
    my $two = shift || '';
    return qq($one\n<script src="/library.js"></script>\n$two);
}
while (<*.tmpl>) {
  my $str = fead_file($_);
  $str =~ s/$search_re/$replace->($1, $2)/ge;
}
0 голосов
/ 02 августа 2011

Ну, вы не можете найти и "a", и "b", когда конкретно говорите ИЛИ (|).Кроме того, вы не можете объединить строки, поместив имя переменной рядом с текстом, например $1foo.

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

s/(a)/$1 . "foo"/ge || s/(b)/"foo" . $1/ge;

Это может сработать.Если первый работает, второй не будет выполнен (ИЛИ короткого замыкания).

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