4

尝试在 Perl 中清除一些变量,下面的代码效果很好:

if ($year =~ /^(\d{4})$/) {
        $year = $1;
} else {
        &invalid("year");
}

在上面的例子中,$1 包含 $year(如果有效)。但是,在使用?:运算符时,$1 在有效时包含“1”:

($year =~ /^(\d{4})$/) ? $year = $1 : &invalid("year");

任何人都看到我可能有错吗?我很困惑为什么会这样。它只发生在这台机器上。或者更确切地说,我已经成功使用了 ? 运算符用于返回多年的正确匹配变量。我还没有在任何其他机器上尝试过这段代码。

This is Perl, v5.8.8 built for x86_64-linux-thread-multi
4

3 回答 3

6

注意这里的优先级。

对比http://codepad.org/vEPnhWfH可以按预期工作,而http://codepad.org/nXVU5CA7则不能。当然,我稍微调整了代码以避免调用invalid,但我怀疑这可能是问题的根源。

在这两种情况下,虽然都$1包含“2011”,所以也许你应该显示额外的代码,正如 mu 在第一条评论中所要求的那样。

更新

我更改了键盘示例以使用调用&invalid,但错误没有出现。

sub invalid {
    print("INVALID\n");
}

sub check_with_if {
    print("Trying with if-statement\n");
    my $year = shift;
    if ($year =~ /^(\d{4})$/) {
        $year = $1;
    } else {
        &invalid($year);
    }
    print("\$1 is $1 and \$year is $year"."\n");
}

sub check_with_conditional {
    print("Trying with conditional expression\n");
    my $year = shift;
    ($year =~ /^(\d{4})$/) ? $year = $1 : &invalid($year);
    print("\$1 is $1 and \$year is $year"."\n");
}

check_with_if("2011");
check_with_conditional("2011");

输出是

Trying with if-statement 
$1 is 2011 and $year is 2011
Trying with conditional expression
$1 is 2011 and $year is 2011

http://codepad.org/z22GMEcn

编辑 2也适用于 Mac 上的 5.12.3。

我同意 Jonathan 的观点,您可能在 5.8.8 中发现了一个已修复的错误。如果您非常好奇,您可以按照自己的方式完成 Perl 更改,例如:

于 2011-09-06T04:25:04.170 回答
5

Damien Conway 的 Perl Best Practices 解释了使用匹配变量$1等的一些陷阱,其中之一是:

  • 如果正则表达式不匹配任何内容,$1则不会变为undef,但会保留其先前的值(当然,在大多数情况下是 undef)

我的直觉告诉我你的上下文有问题 - 你的表达式可能在标量上下文中进行评估,因此在它有效时返回匹配的数量。

所以,我会尝试重写代码,如:

($year) = ( $year =~ /^(\d{4})$/) or &invalid("year");
于 2011-09-06T05:07:04.173 回答
3

使用 Perl 5.14.1(在 MacOS X 10.7.1 上),此脚本似乎可以正常工作:

use strict;
use warnings;

my $year = "1984";

sub invalid
{
    my($year) = @_;
    print "Invalid year $year\n";
}

if ($year =~ /^(\d{4})$/)
{
    $year = $1;
}
else
{
    &invalid("year");
}


print "Year1: $year\n";

$year = "1984";
($year =~ /^(\d{4})$/) ? $year = $1 : &invalid("year");

print "Year2: $year\n";

它产生:

Year1: 1984
Year2: 1984

如果相同的脚本在 Perl 5.8.8 中产生了不同的答案,那么可能您遇到了一个已修复的错误并且升级是有序的。如果 Perl 5.8.8 产生相同的答案(与 Perl 5.14.1),那么您还没有描述您的问题,以便我可以理解并重现问题。

于 2011-09-06T04:31:19.697 回答