2016-01-20 18 views
5

私はこのJavaアプリケーションをサポートしています。ここで、devsはRegExに基づいたフィルタリングを実装しています。可能な限り汎用的になるために、MULTILINEフラグを使用してパターンをコンパイルします。

先日私は予期せぬことに気づいた。 Javaでは、パターン"^\\s*$"""とMULTILINEフラグが一致しません。そのフラグなしでマッチします。

Pattern pattern = Pattern.compile("^\\s*$", Pattern.MULTILINE); 
Matcher matcher = pattern.matcher(""); 

System.out.println("Multiline: "+matcher.find()); 

pattern = Pattern.compile("^\\s*$"); 
matcher = pattern.matcher(""); 

System.out.println("No-multiline: "+matcher.find()); 

これは次の出力が生成さ

Multiline: false 
Non-Multiline: true 

同じ結果がmatches()ために見ることができます。

System.out.println("Multiline: " + ("".matches("(?m)^\\s*$"))); 
System.out.println("No-multiline: " + ("".matches("^\\s*$"))); 

私はすべてのケースが一致することを期待します。
Pythonでは、これが当てはまります。この:

import re 

print(re.search(r'^\s*$', "", re.MULTILINE)) 
print(re.search(r'^\s*$', "")) 

ができます:

Perlで
<_sre.SRE_Match object; span=(0, 0), match=''> 
<_sre.SRE_Match object; span=(0, 0), match=''> 

は、どちらの場合も同様に一致し、私はそれがPHPのために同じであることを覚えてだと思います。

Javaがこのケースを処理する方法の背後にある理由を誰かが説明できるかどうか、本当に感謝します。

+0

あなたは正しいです。これは、matches()とfind()の違いによるものかどうかをテストしています。両方の場合とも、両方の方法で再現可能です。両方のケースでfind()を使用するように質問を更新しました – shmee

+0

私は、IDEONEデモへのリンク(http://ideone.com/1ZoX3V)を共有して、問題が 'find()'であることを示したかったので、あまりにも。 –

+1

[この質問](http://stackoverflow.com/questions/8896201/regular-expression-doesnt-match-empty-string-in-multiline-mode-java)いくつかの洞察力を提供することがあります。 – sgbj

答えて

3

空の文字列を正規表現に渡します。 Pattern.MULTILINEでは、^は、文字列の先頭に一致することが予想されますが、in Javaそれは少し異なることができます:

MULTILINEモードは、入力の開始時および任意の行終端後、その後^試合を活性化されれば入力の末尾を除いて

文字列が空であるため、入力の開始は終了です。

注:デフォルトでは、フラグを渡し、実際に、あなたはパターンが文字列の開始時に一致させたい場合は、あなたの代わりに$の文字列の終わりのための代わりに^\z\Aを使用することができますPattern.MULTILINEでも開始/終了文字列と一致します(空の文字列でも\\A\\s*\\zテストに合格します)。

+2

私は '^'が文字列の先頭で常に一致するようにドキュメントを理解していて、実際に空で行末に行終端記号がある場合は例外が適用されます。代わりに '\\ A'と' \\ z'を使用して頂きありがとうございます。 – shmee

関連する問題