【问题标题】:Use of uninitialized value $2 in concatenation (.) or string在连接 (.) 或字符串中使用未初始化的值 $2
【发布时间】:2014-08-02 06:42:07
【问题描述】:

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

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

功能:

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

谢谢!

【问题讨论】:

    标签: perl


    【解决方案1】:

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

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

    您可能会注意到$2-group 是完全可选的。如果$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) 将不会被初始化。如果您随后尝试在替换表达式 (&lt;TMPL_VAR NAME=\"$1\"$2&gt;) 中使用该未初始化变量,您将收到您在问题中提到的错误。

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

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

    【讨论】:

      【解决方案3】:

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

      似乎函数重写了,例如: [%something other params%] 到: &lt;TMPL_VAR_NAME="something" other params&gt;

      字符串看起来应该是这样的: [%something%],仅匹配([^ ]+?),但不匹配( .*)

      查看出现这个错误的文件,应该可以找到麻烦的字符串。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-20
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-27
        相关资源
        最近更新 更多