4

正規表現について質問があり、答えようとすると、別の奇妙なことがわかりました。

String x = "X";
System.out.println(x.replaceAll("X*", "Y"));

これはYYを印刷します。どうして??

String x = "X";
System.out.println(x.replaceAll("X*?", "Y"));

そしてこれはYXYを印刷します

気が進まない正規表現が「X」文字と一致しないのはなぜですか?ありますが"noting"X"nothing"、なぜ最初に3つのシンボルに一致せず、2つに一致し、次に3つではなく1つに一致するのでしょうか。2番目の正規表現は"nothing"sにのみ一致し、一致しませんXか?

4

3 に答える 3

8

それらを順番に考えてみましょう:

"X".replaceAll("X*", "Y")

2つの一致があります:

  1. 文字位置0で、X一致し、。に置き換えられYます。
  2. 文字位置1で、空の文字列が一致Yし、出力に追加されます。

最終結果:YY

"X".replaceAll("X*?", "Y")

2つの一致もあります:

  1. 文字位置0で、空の文字列が一致Yし、出力に追加されます。この位置の文字はX、一致によって消費されなかったため、出力にそのままコピーされます。
  2. 文字位置1で、空の文字列が一致Yし、出力に追加されます。

最終結果:YXY

于 2012-02-10T13:35:38.773 に答える
1

*は、「0以上」を意味するため、トリッキーな「数量詞」です。したがって、「0×X」(つまり、空の文字列)にも一致します。

私は使うだろう

"X".replaceAll("X+", "Y")

これは期待される動作をします。

于 2012-02-10T13:40:50.570 に答える
0

最初の例では、「Greedy」数量詞を使用しています。これは、最初の一致を試行する前に入力文字列が完全に読み取られることを意味するため、最初に試行される一致は入力全体です。入力が一致する場合、マッチャーは入力文字列を通過し、文字列の最後で長さゼロの一致を実行するため、2つの一致が表示されます。貪欲なマッチャーは、最初の一致の試行が成功する前に、文字Xの前に長さゼロの一致に戻ることはありません。

2番目の例では、「Greedy」の反対を行う「Reluctant」数量詞を使用しています。最初から開始し、今後は1文字ずつ一致させようとします(必要な場合)。したがって、「X」文字が一致する前の長さゼロの一致では、マッチャーが1つ進みます(そのため、出力に「X」文字が表示されます)。次の一致は、「X」の後の長さゼロの一致になります。 "。
ここに良いチュートリアルがあります:http://docs.oracle.com/javase/tutorial/essential/regex/quant.html

于 2012-02-10T14:18:06.180 に答える