4

Perl でいくつかの変数を untaint しようとすると、次のコードがうまく機能します。

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 でも動作します。

5.8.8 で修正されたバグを発見した可能性があるというジョナサンに同意します。非常に興味がある場合は、次のような Perl の変更に取り組むことができます。

于 2011-09-06T04:25:04.170 に答える
5

Damien Conway の Perl Best Practices では、マッチ変数などを使用する際の落とし穴について説明しています$1。そのうちの 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 に答える