Perl 在串联(.)或字符串中使用未初始化的值$2

Perl 在串联(.)或字符串中使用未初始化的值$2,perl,Perl,我在另一台服务器上传输了我的站点,发生了以下错误: 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

我在另一台服务器上传输了我的站点,发生了以下错误:

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
36子小波滤波器{
37
38 my$filter=sub{
39我的$text\u ref=班次;
40$$text\u ref=~s/\[\%([^]+?)(.*)\%\]//g;
41    };
42
43返回$filter;
44
45}#子WT_滤波器

谢谢

查看正则表达式:

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

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

在这种情况下,将不会初始化第二个反向引用变量(
$2
)。如果然后尝试在replace表达式(
)中使用未初始化的变量,您将得到问题中提到的错误

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

my $filter = sub {
    my $text_ref = shift;
    {
        no warnings qw/uninitialized/;
        $$text_ref =~ s/\[\%([^ ]+?)( .*)?\%\]/<TMPL_VAR NAME=\"$1\"$2>/g;
    }
}
my$filter=sub{
我的$text\u ref=shift;
{
无警告qw/未初始化/;
$$text\u ref=~s/\[\%([^]+?)(.*)\%\]//g;
}
}

regexp的第二个括号与任何内容都不匹配

功能似乎重写了,例如:
[%something other params%]
致:

看起来这根绳子一定是这样的:
[%something%]
,仅匹配
([^]+?)
,但不匹配
(.*)


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

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

/
  \[\%
  ( [^ ]+? )  # $1
  ( [ ].* )?    # $2
  \%\]
/x
您可能会注意到,
$2
-组是完全可选的。如果
$2
的模式不匹配,它将被设置为
undef
。如果变量名和结束符
%]
[%foo bar%]
之间没有至少一个空格,则不匹配

可能的解决办法包括:

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

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

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

    谢谢,这很有效!罗比也有同样的答案,但你的答案更完整。同意+对于
    /
    语法,我也提供了1个。
    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