2011-04-03 6 views
3

RegExを使用して複数行の文字列を解釈しようとしていて、文字列に改行文字が含まれていると一致しないことが判明しました。私はアンカーを使用していないので、MULTILINEモードを使用していません。 APIドキュメントによると:複数行モードでJava RegExおよび改行 - バグまたは予期される動作?

表現^ と$の試合直後または直前に、 それぞれ、ラインターミネータまたは入力シーケンスの 終わり。デフォルトでは、 の式は、 の開始シーケンスと、 入力シーケンス全体の終わりにのみ一致します。要するに

:それは明らかに、このフラグが唯一のアンカーがどのように動作するかを変更し、のようなものが「あなたの文字列に改行が含まれている場合、あなたは間違いなく、これを使用するべきではない」と言うことを言います。

public static void main(String[] args) { 
    Pattern p = Pattern.compile(".*"); 

    Matcher m1 = p.matcher("Hello"); 
    System.out.println("m1: " + m1.matches()); // true 

    Matcher m2 = p.matcher("Hello\r\n"); 
    System.out.println("m2: " + m2.matches()); // false 
} 

これは実際にはバグですか、いくつかのドキュメントを見逃しましたか?または、JAVAは私のパターンが失敗したRegExの方言を使用しますか?私はjdk1.6.0_21を使用しています。 Pattern docsから

+0

標準のJava APIを使用していて、期待通りに動作しない場合は、バグを発見したという理論を追求するのではなく、疑問を抱くべきことが* APIの理解*です。 –

+0

@Stephen私は知っている、私は知っている。しかし、アンカーを使わなくても、全体の文字列とのマッチが一致することは決してありませんでした。 JAVA APIは、これまでコンピューティング業界でこれまで遭遇したことの中で最も一貫性があり、うまく計画されていたので、私が推測したように、このメソッドがうまくいくと信じていました。 – vbence

+0

Java APIが「一貫性があり十分に計画されている」と考えるならば、十分注意を払っているわけではありません。そんなものではない! – tchrist

答えて

3

:DOTALLフラグが指定されていない限り

正規表現は.ラインターミネータ を除く任意の 文字に一致します。

m2.matches()をtrueにするには、DOTALLフラグを指定する必要があります。

+0

私は赤すぎますが、そのパターンは '^。* $'なんかそんなものではないことに注意してください。私はアントロを使用していないので、 'Hello'も第2のケースで一致するはずです。 – vbence

+3

'matches()'は*全体の文字列が正規表現 "'。* '"と一致するかどうかを調べます。 '。*'は "0回以上の改行を除くすべての文字"を意味します。したがって、 'H'は' e'にマッチし、その後は 'l'、それから' o'にマッチし、それが '\ r'に到達するとそれはもはやマッチしないので、falseを返します。わかりますか?このコードは、アンカーではなく '.'文字の動作と関係しています。 – Philip

+0

したがって、 'DOTALL'フラグを有効にした場合、' m2'は 'Hello'にマッチし、' \ r \ n'に到達します。仕様では、 "正規表現' .'は行終端文字**を含む任意の文字**に一致します。だから、 'm2'は' \ r'と '\ n'にマッチしてtrueを返します。 – Philip

関連する問題