2011-09-12 10 views
0

私は最近、Javaの正規表現エンジンに関係するいくつかの奇妙な動作に出くわしました。Javaの正規表現ダークコーナー... charsの順序は正規表現の意味を変えますか?

は、いくつかの検証を書くとき、私はそうのように、私の正規表現に角括弧を追加する必要:

"[^a-zA-Z0-9_/[email protected] ]" // original expression 
"[^a-zA-Z0-9_/[email protected] /]/[]" // first modificiation 

しかし...この実装に失敗しました。実験の後、私はスペースをcharの最後まで移動すると動作することを発見しました。 hereがリストされているよう

"[^a-zA-Z0-9_/[email protected]/]/[ ]" // final working modification 

は今、この表現を使用し、呼び出し元のコードは、String.replaceAll(String, String)方法を使用していました。

私の質問は...誰もこの空間の配置がこの正規表現の意味を変える理由について、良い技術的考えを持っていますか?本当に問題ではありません。

[編集済み] コメントと回答 - 組み込みのStringメソッドを使用すると、誤った動作が発生することがあります。私のランタイム環境では、String.replaceAll(String, String)のドキュメントを読むと、それは明らかにそれがPattern.compile(regex).matcher(str).replaceAll(repl)と同じ機能であると書かれていますが、私はバグを報告します。

+2

** **それが失敗しましたか?私は['PatternSyntaxException'](http://download.oracle.com/javase/7/docs/api/java/util/regex/PatternSyntaxException.html)を取得したと思います。 –

+0

'/]/['を書くと、文字クラスに大括弧を入れたいですか?そうであれば、間違ったエスケープ文字のために失敗し、2番目のエスケープ文字が作成されました。 – stema

+0

コンパイルエラーはありませんでした。括弧を正しくキャッチしないと失敗しました。私はそれ以来、私の誤った構文を修正しました。ありがとう! – avgvstvs

答えて

9

間違ったエスケープ文字を使用しています。\で、/ではありません。

また、私はあなたが.ニーズが文字グループにエスケープすることを考えた場合、あなたのキャラクターのグループが/.かを含めるしたいかどうかわからないんだけど(それはエスケープする必要はありません:それは常にリテラルを表し文字グループ内の.)。

[^a-zA-Z0-9_/[email protected] /]/[]をコンパイルしようとすると、それはこの例外を与える:

java.util.regex.PatternSyntaxException: Unclosed character class near index 20 
[^a-zA-Z0-9_/[email protected] /]/[] 
        ^
    at java.util.regex.Pattern.error(Pattern.java:1713) 
    at java.util.regex.Pattern.clazz(Pattern.java:2254) 
    at java.util.regex.Pattern.sequence(Pattern.java:1818) 
    at java.util.regex.Pattern.expr(Pattern.java:1752) 
    at java.util.regex.Pattern.compile(Pattern.java:1460) 
    at java.util.regex.Pattern.(Pattern.java:1133) 
    at java.util.regex.Pattern.compile(Pattern.java:823) 

これは、その時点での文字クラスに問題があることを示しています。そして、実際には:空の文字クラス[]が有効ではありません!

[^a-zA-Z0-9_/[email protected] /]/[]

は、 "それは>不正な形式であるため、コンパイルに失敗し<続くスラッシュ /続く(AZ、AZ、0-9、 _/.@または /を)一致しない文字を、" 意味します。何をしたい

は、おそらく "-Z、-Z、0-9、_.@]または[と一致しない文字" である[^[email protected] \]\[]です。 (彼らは同様Stringリテラルで特別な意味を持っているので!)リテラルStringでそれを記述する場合

\を倍増することを忘れないでください:

Pattern regex = Pattern.compile("[^[email protected] \\]\\[]"); 
+0

私は私の構文を変更しましたが、私はこの誤った方法で実行したときに全く例外はありません。 (冗談ではありません。私のマシンではコンパイルされ、うまく走っていました...私はそれを使って6週間働いています)そして、コンパイラのサイレンシングはありません。 – avgvstvs

+0

@avgvstvs:** 'java.util.regex.Pattern.compile(" [^ a-zA-Z0-9 _ /。@ /]/[] ");'を ' main'メソッドを実行し、マシン上で実行しますか?多分もっと寛大である別の 'Pattern'実装を使用しているかもしれません。 –

+1

これは確かに失敗しますが、OPのように 'String.replaceAll(String、String)'メソッドを使用しているときには失敗します。私はこれが '.replaceAll()'の実装における明白な不完全性を強調していると思います。 – avgvstvs