4

元の質問と同様に、この質問を更新しました。私が追いかけていた問題は、まったく別のバグであることが判明しました(このコンテキストでは興味深いものではありません)。しかし、私がテストで行った2次の間違いは、他の人が遭遇して非常に興味深い洞察を持った答えを生み出した可能性があるため、これを質問としてここに残しておきます。

先行ゼロが原因で正規表現が一致していないように見える問題を追跡しようとしていました。次の正規表現のすべてがコマンドラインテストで一致しなかったことがわかりました。

"005630" =~ /^0056(10|11|15|20|21|25|30|31)$/
"005630" =~ /0056(10|11|15|20|21|25|30|31)/  
"005630" =~ /56(10|11|15|20|21|25|30|31)/
"005630" =~ /..56(10|11|15|20|21|25|30|31)/
"005630" =~ /..5630/
"005630" =~ /005630/
"005630" =~ /^005630$/
"005630" =~ /5630/
"005630" =~ /(0)*5630/
"005630" =~ /5630/g
"005630" =~ m/5630/g

これは一致しました:

"x005630" =~ /0056(10|11|15|20|21|25|30|31)/

他の人にも似ています。つまり、先頭の文字を追加すると、機能します。

テストコードは(CygwinbashでCygwinPerl v5.10.1を使用してテストされました):

perl -e "print ( "005630" =~ /0056(10|11|15|20|21|25|30|31)/)"   # does not display a true value
perl -e "print ( "x005630" =~ /0056(10|11|15|20|21|25|30|31)/)"  # displays a true value

ここでの引用は明らかに間違いです("で引用された文字列でエスケープなしを使用することはできません")。しかし、引用符が正しくないにもかかわらず、2行目が機能する理由がわかりませんでした。

注:これは、正規表現がない他の状況でも発生する可能性があります。

4

1 に答える 1

10

コマンドを与えられた理由

perl -e "print ( "005630" =~ /0056(10|11|15|20|21|25|30|31)/)"
perl -e "print ( "x005630" =~ /0056(10|11|15|20|21|25|30|31)/)"

2行目だけが一致を出力します。これは、Perlが8進数の リテラルをサポートしていることです。あなたが理解したように、あなたのシェルは引用符を食べているので、あなたは実際にステートメントを実行しています:

print ( 005630 =~ /0056(10|11|15|20|21|25|30|31)/);
print ( x005630 =~ /0056(10|11|15|20|21|25|30|31)/);

ゼロで始まり、直後に小数点が続かない数値リテラル(引用符で囲まれていない数値)は、8進数として扱われます。

perl -e "print 005630 . ''"  # prints 2968
perl -e "print x005630 . ''" # prints x005630

. ''ここでは、ベアワードが文字列として扱われるようにするために必要です。この=~例では、オペレーターがこれを行います。)

したがって、正規表現が一致しない理由は、文字列に思ったとおりの文字列が含まれていないためです。

于 2012-11-22T14:39:28.180 に答える