使用正则表达式将字符串拆分为数组时出现 Perl 评论错误

Perl critic error on splitting string into array using regexp

sub func {
    my ($n) = @_;
    return unless ($n);
    my @array;
    push @array,  while $n =~ /
            ((?:
              [^(),]+ |
              ( \(
                (?: [^()]+ | (?2) )*
              \) )
            )+)
            (?: ,\s* | $)
            /xg;

    return \@array;
    }

    for my $item (@array) {
        if (index($item, '$n') != -1) {
           print "HELLO\n";
        }
} 

我有上面的正则表达式将一些字符串拆分成数组。它工作正常。

问题是:

Perl 评论家给出了以下错误。请告诉我如何解决这个问题。

Capture variable used outside conditional at line 150, 
    near 'push @array,  while $n =~ /'.  (Severity: 3)
Use '{' and '}' to delimit multi-line regexps at line 150, 
    near 'push @input_expression,  while $n =~ /'.  (Severity: 1)
String *may* require interpolation at line 168, 
    near '$item, '$n''.  (Severity: 1)

第一个是 IMO 误报,因为 while 在这里充当条件 - 除非正则表达式匹配,否则 push @array, 不会执行,这正是政策想要的(将 --verbose 11 添加到 perlcritic 调用以查看解释)。在这种情况下,我认为抑制政策是安全的,如下所示。

第二个很容易修复,只需将 $n =~ /.../xg 替换为 $n =~ m{...}xg

push @array,   ## no critic (ProhibitCaptureWithoutTest)
    while $n =~ m{ ... }xg;

这会抑制这两条消息。

附带说明一下,运行宁 perlcriticbrutal 严重性是 IMO 有点极端,它会抱怨该片段中的许多其他内容。就个人而言,当我使用它时,我 运行 perlcriticharsh (-3) 有一些自定义级别的策略。

编辑: 至于你的第三条 perlcritic 消息,你后来添加到你的 post 中,看起来已经在 your other post.

Perl Critic 没有给出任何错误。它违反了政策。

要修复第一个问题,请将循环从修饰符更改为普通 while 循环并将变量命名为:

    while ($n =~ /
        ...

    /xg) {
        my $match = ;
        push @array, $match;
    }

要修复第二个,只需将 /.../ 更改为 m{...}

在我看来,使用你不了解的策略是没有意义的。有时,可能有很好的理由打破其中的一些;盲目地追随 Perl Critic(尤其是在更严厉的层面上)不会给你带来任何东西。