外部"如果"的Perl匹配不会在循环上重置$ 1

Joe*_*ger 4 regex perl

我正在修补Zoidberg Perl shell以修复现代Perl版本在测试时抛出的一些错误.请注意,我不是原作者,也不是我批评他.我遇到了一个有趣的问题,我想要一点历史.

下面的代码采用一系列输入,每个条带关闭和结束sigil.然后它将该sigil存储在一个变量中,如果它没有找到它存储0.原始文件中的代码看起来像测试A,并且必须已经工作,直到并包括perl v5.8给出cpantesters结果.无论如何问题是如果s ///不在"if"测试中,循环时$ 1变量会持续使用最后一个值.这是我的测试.我想知道人们是否可以解释为什么会发生这种情况和/或为什么它曾经工作,我想我明白发生了什么.

#!/usr/bin/perl

use strict;
use warnings;

my @a = qw/n a$ b@ c/;
my @b = @a;
my @c = @a;

print "Test A -- Doesn't work (c !-> 0)\n";
for (@a) {
  s/([\$\@\%])$//;
  my $arg = $1 || 0;
  print $_ . " -> " . $arg . "\n";
}

print "\nTest B -- Works\n";
for (@b) {
  my $arg;
  if (s/([\$\@\%])$//) {;
    $arg = $1;
  }
  $arg ||= 0;
  print $_ . " -> " . $arg . "\n";
}

print "\nTest C -- Works, more clever\n";
for (@c) {
  my $arg = s/([\$\@\%])$// ? $1 : 0;
  print $_ . " -> " . $arg . "\n";
}
Run Code Online (Sandbox Code Playgroud)

cjm*_*cjm 7

来自perlre:

注意: Perl中的失败匹配不会重置匹配变量,这使得编写测试一系列更具体案例的代码更容易,并记住最佳匹配.

但是你是对的,测试A确实像5.8.9中的其他两个一样工作.我在5.10.0发行说明中找不到任何解释它的内容,但5.10中有许多RE更改,其中一个必须影响到这一点.我不认为5.8的行为是有意的.

  • "错误报告是失败的匹配(实际上是失败的s /// g)*是*重置匹配变量,所以它没有按照记录的方式工作." 它使用5c5e4c245abefef949ee72dd179eff31d923dcb2在5.6.0附近引入,并使用c74340f9cdee6010339b6bfd0e8b0dc8bc875344在5.10.0中修复. (2认同)