假设我必须使用单个替换进行此替换,那么避免此错误的首选方法是什么:
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;替换然后将它们添加到模板中。必须在每次提交时运行此脚本两次会引入太多开销,显然......所以说他们......
答案 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;
}