替代中的未初始化反向引用

时间:2011-08-02 15:35:24

标签: regex perl

假设我必须使用单个替换进行此替换,那么避免此错误的首选方法是什么:

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;'

此处的目标是根据$str包含的内容打印“afoo”或“foob”。

我可以使用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;
}

但是更复杂的是,基本上上面的代码只是从数据库中读取以获得搜索&amp;替换然后将它们添加到模板中。必须在每次提交时运行此脚本两次会引入太多开销,显然......所以说他们......

4 个答案:

答案 0 :(得分:2)

你可以:

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

(在5.10 +上使用//而不是||)

答案 1 :(得分:1)

仍适用于/ g:

s/(a)|(b)/ ($1 // '') . 'foo' . ($2 // '') /ge

答案 2 :(得分:0)

嗯,当你具体说OR(|)时,你找不到“a”和“b”。此外,您不能通过将变量名称放在文本旁边来连接字符串,例如$1foo

我不太确定您对开销的看法,但您需要检查匹配才能进行正确的替换。

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

这可能有用。如果第一个工作,第二个将不会执行(短路OR)。

答案 3 :(得分:0)

与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;
}