2016-12-11 11 views
1

\文字を含む文字列と一致させようとしていますが、期待通りに機能しません。""文字を含む文字列の一致

例えば

:この場合

if ("\\" =~ "\\") { 
    print "true\n"; 
} 

それが動作し、プリントtrueは予想通り。

は、しかし場合には、私は、条件が偽となる\文字、前後に複数の文字を入れて、私は文字を入れた場合if条件がまだ真であるが、それは標準出力

if ("DATA\\DATA" =~ "DATA\\DATA") { 
    print "true\n"; 
} 

には何も印刷されません。 \文字(DATA\\または\\DATA)の1面に表示されます。

答えて

-2
$input = "DATA\\DATA"; 
if ($input =~ /\\/) { print "true\n"; } else { print "false\n"; } 

regular expressionsにチェックしてください。

+0

@melpomeneええ、最近はJavaにも慣れていて、Perlを長い間チェックしていませんでした。それを指摘してくれてありがとう(皮肉なことに)。 – m0skit0

3

perlopから:

Binary "=~" binds a scalar expression to a pattern match. … The right argument is a search pattern, substitution, or transliteration. … If the right argument is an expression rather than a search pattern, substitution, or transliteration, it is interpreted as a search pattern at run time. Note that this means that its contents will be interpolated twice.

=~の右側には、正規表現であることが予想されます。

ここに文字列を入力すると、正規表現に変換されます。だから、

あなたが言うとき:

if ("\\" =~ "\\") { 
    print "true\n"; 
} 

あなたが得る:

Trailing \ in regex m//

リテラル\\終わりに続い\があるので(\はRegexに変換される文字列\に変換され、依然として\)。

これは有効な正規表現ではないため、エラーが発生します。なぜあなたは考えているのかわかりませんこの場合、それはうまく動作し、期待通りに印刷されます。

リテラルDATA\\DATAは、文字列DATA\DATAに変換され、正規表現DATA[^0-9]ATAに変換されます。これはDATA\DATAと一致しません。これは、2つの文字が1つの非数字だけを期待するためです。


=~を使用する場合は、実際の正規表現をRHSに配置します。はるかに簡単です。

+3

'\ D'は' [^ 0-9] 'と全く同じではありません。なぜなら、前者もすべてのUnicode数字を除外しているからです。 – melpomene

+0

初めて、私はまさにあなたが現在いるように思っています。 「\\」の代わりに「\\\\」を使用する必要があります。しかし、私の最初のコードはまだコンピュータで動作していて、2番目のコードは "\\\\"を使用しても動作しないというのは混乱しています。 –

7

私はあなたの最初のコードをしようとすると、私は実際にこのエラーが出る:

Trailing \ in regex m/\/ at foo.pl line 1. 

問題が何であるかのヒントです。

=~オペレータは、いくつかの形式をとることができます。通常、音訳の場合は$str =~ tr/.../.../、正規表現の検索/置換の場合は$str =~ s/.../.../、正規表現の場合は$str =~ m/.../となります。

あなたのコードでは、これらのどれも使用していません。代わりに、一般的な$str =~ EXPR形式を使用します。これはEXPRを文字列として評価し、その文字列の内容を正規表現として解釈します(m//のように通常のマッチを実行します)。

あなたの場合(コード1)、結果の文字列は単一のバックスラッシュ(\)で構成されます。正規表現ではバックスラッシュの後に何かが続く必要があるため、これは有効な正規表現ではありません。そのため、上記のエラーが発生します。

他の例(コード2)では、結果の文字列はDATA\DATAです。正規表現として解釈すると、これはDATAに続いて、その後にATAが続く、数字以外の文字(つまり、\Dは正規表現での意味)と一致します。

この問題を解決するには、することができますいずれかをダブルすべてのバックスラッシュ - 、または単に最初の場所で文字列を使用しない(​​文字列処理は、文字列リテラルDATA\DATAをマッチングするための正規表現である、DATA\\DATAにこのターン):

は、
if ("DATA\\DATA" =~ m/DATA\\DATA/) { 
    print "yay\n"; 
} 

m//を使用すると、Perlは正規表現を書いていることを知っているので、正規表現エスケープの上に文字列エスケープを処理する必要はありません。

+0

非常に良い説明。私は最近[関連する質問](http://stackoverflow.com/q/39498206/5830574)があり、これは完璧な追加です。 – PerlDuck

+0

初めて、私はまさにあなたが現在いるように思っています。 「\\」の代わりに「\\\\」を使用する必要があります。しかし、私の最初のコードはまだコンピュータで動作していて、2番目のコードは "\\\\"を使用しても動作しないというのは混乱しています。 –

+0

@TuanAnhHoang使用している正確なコードを表示してください。 – melpomene

関連する問題