在连接(。)或字符串中使用未初始化的值$ 2

时间:2014-08-02 06:42:07

标签: perl

我将我的网站转移到另一台服务器上并发生了此错误:

PERL: 在连接(。)中使用未初始化的值$ 2或在/Toolbox.pm第40行使用字符串。

功能:

36 sub WT_filter{
37 
38    my $filter = sub {
39         my $text_ref = shift;
40         $$text_ref =~ s/\[\%([^ ]+?)( .*)?\%\]/<TMPL_VAR NAME=\"$1\"$2>/g;
41    };
42
43    return $filter;
44
45 } #sub WT_filter

谢谢!

3 个答案:

答案 0 :(得分:8)

你有正则表达式/\[\%([^ ]+?)( .*)?\%\]/。或写得更具可读性:

/
  \[\%
  ( [^ ]+? )  # $1
  ( [ ].* )?    # $2
  \%\]
/x

您可能会注意到$2 - 组是完全可选的。如果$2的模式不匹配,则会将其设置为undef。如果变量名称与结束%][%foo-bar%]之间至少有一个空格,则不匹配。

可能的解决方案包括:

  • 更改$2的模式,以便它也接受零长度字符串:( .* )

  • 在插值前使用$2的默认值:

    s{\[\%([^ ]+?)( .*)?\%\]}{qq[<TMPL_VAR NAME="$1"] . ($2 // q[]) . q[>]}eg
    

    (仅适用于perl 5.10开始)

  • 在过滤器范围内关闭此警告:no warnings'uninitialized';

请注意,您的替换机制易受XML注入的影响,并且当变量[% … %]块在多行上延伸时,或者当两个变量在同一行上时,会出现问题。假设escape()转义了一些数据以便在XML中安全使用,那么以下内容应该有效:

s{
  \[%
  (\S+?)  # $1 is a sequence of non-space characters
  (?: \s+ ["]([^"]+)["] )?  # $2 is anything inside double quotes
  %\]
}{
  (defined $2)
  ? (sprintf q[<TMPL_VAR NAME="%s" "%s">], escape($1), escape($2))
  : (sprintf q[<TMPL_VAR NAME="%s">], escape($1))
}gsex

答案 1 :(得分:2)

看着你的正则表达式:

\[\%([^ ]+?)( .*)?\%\]

您尝试提取两个群组:([^ ]+?)( .*)?。请注意,第二组后面跟一个问号(?),将其标记为可选。

现在,假设您尝试匹配第二个可选组不存在的文本,例如[%whatever%]

在这种情况下,第二个反向引用变量($2)将不会被初始化。如果您尝试在替换表达式(<TMPL_VAR NAME=\"$1\"$2>)中使用该未初始化的变量,则会收到您在问题中提到的错误。

要解决此问题,请尽可能更改正则表达式,或者您可以创建暂时禁用警告的小范围:

my $filter = sub {
    my $text_ref = shift;
    {
        no warnings qw/uninitialized/;
        $$text_ref =~ s/\[\%([^ ]+?)( .*)?\%\]/<TMPL_VAR NAME=\"$1\"$2>/g;
    }
}

答案 2 :(得分:1)

正则表达式的第二个括号与任何内容都不匹配。

似乎功能重写例如: [%something other params%] 至: <TMPL_VAR_NAME="something" other params>

似乎字符串必须如下所示: [%something%],仅匹配([^ ]+?)但不匹配( .*)

查看发生此错误的文件,您应该能够找到麻烦的字符串。