1

Java (1.6.20) で一致する先頭/末尾の $ を持つ正規表現を取得するのに問題があります。

このコードから:

System.out.println( "$40".matches("\\b\\Q$40\\E\\b") );
System.out.println( "$40".matches(".*\\Q$40\\E.*") );
System.out.println( "$40".matches("\\Q$40\\E") );
System.out.println( " ------ " );
System.out.println( "40$".matches("\\b\\Q40$\\E\\b") );
System.out.println( "40$".matches(".*\\Q40$\\E.*") );
System.out.println( "40$".matches("\\Q40$\\E") );
System.out.println( " ------ " );
System.out.println( "4$0".matches("\\b\\Q4$0\\E\\b") );
System.out.println( "40".matches("\\b\\Q40\\E\\b") );

次の結果が得られます。

false
true
true
 ------ 
false
true
true
 ------ 
true
true

最初の 2 つのブロックの先頭の false が問題のようです。つまり、先頭/末尾の $ (ドル記号) は、\b (単語境界) マーカーのコンテキストで適切に取得されません。

\b を .* に置き換えるか、すべて一緒に削除すると、目的の結果が得られるため、ブロック内の真の結果は、引用符で囲まれたドル記号自体ではないことを示しています。

最後の 2 つの「真」の結果は、問題が内部的に引用された $ にも、引用された式「\Q ... \E」内の単語境界 (\b) の一致にもないことを示しています。

これは Java のバグですか、それとも何か不足していますか?

4

2 に答える 2

3

これは、\b単語境界に一致するためです。また、文字の直前または直後の位置$は、必ずしも単語境界としてカウントされません。

単語境界は と の間の位置で\wあり\W$の一部ではありません\w。文字列「bla$」の例では、単語の境界は次のとおりです。

" b l a $ "
 ^----------- here

" b l a $ "
       ^----- here

" b l a $ "
         ^--- but not here
于 2010-07-23T16:10:16.760 に答える
1

Tomalak はそれを釘付けにしました - それは単語境界マッチングに関するものです。私はそれを理解して質問を削除しましたが、他の人のためにオープンにしておくというウィルのアドバイスは適切です.

\b実はこいつが犯人だった。

結論の 1 つは、最も基本的な (ASCII などの) 用途以外では、Java の組み込みの便利な式は事実上役に立たないということです。例えば。\wASCII 文字のみに一致\bする、それに基づいている、など。

FWIW、私のRegExpは次のようになりました:

   (?:^|[\p{P}\p{Z}])(\QThe $earch Term\E)(?:[\p{P}\p{Z}]|$)

The $earch Term一致させようとしているテキストはどこにありますか。

\p{}Unicode カテゴリです。P基本的に、句読点 ( ) または区切り記号 ( Z) Unicode 文字カテゴリの任意の文字について、私の言葉を破っています。同様に、入力の開始と終了は尊重され ( と^を使用$)、境界マーカーは非キャプチャ グループ ((?:...)ビット) としてタグ付けされますが、実際の検索用語は引用符で囲まれ\Q\E& が一致するグループに配置されます。

于 2010-08-13T18:58:32.913 に答える