15

「境界」の最初の出現によって制限されたキャプチャ グループを見つけるパターンを設定したいと考えています。しかし、今は最後の境界が使用されています。

例えば:

String text = "this should match from A to the first B and not 2nd B, got that?";
Pattern ptrn = Pattern.compile("\\b(A.*B)\\b");
Matcher mtchr = ptrn.matcher(text);
while(mtchr.find()) {
    String match = mtchr.group();
    System.out.println("Match = <" + match + ">");
}

プリント:

"Match = <A to the first B and not 2nd B>"

そして私はそれを印刷したい:

"Match = <A to the first B>"

パターン内で何を変更する必要がありますか?

4

4 に答える 4

45

Make your * non-greedy / reluctant using *?:

Pattern ptrn = Pattern.compile("\\b(A.*?B)\\b");

By default, the pattern will behave greedily, and match as many characters as possible to satisfy the pattern, that is, up until the last B.

See Reluctant Quantifiers from the docs, and this tutorial.

于 2012-10-11T21:14:38.777 に答える
6

Don't use a greedy expression for matching, i.e.:

Pattern ptrn = Pattern.compile("\\b(A.*?B)\\b");
于 2012-10-11T21:14:03.537 に答える
4

*パターンを満たすためにできるだけ多くの文字に一致する貪欲な量指定子です。あなたの例の最後のB出現まで。そのため、消極的なものを使用する必要があります。これは*?、可能な限り少ない文字数になります。したがって、パターンを少し変更する必要があります。

Pattern ptrn = Pattern.compile("\\b(A.*?B)\\b");

docs の「reluctant quantifiers」と、このチュートリアルを参照してください。

于 2012-10-11T22:01:47.247 に答える
1

おそらく、消極的/怠惰にするよりも明確なのは*、 A を探していて、その後に B ではないものがたくさんあり、その後に B が続くと言うことです:

Pattern ptrn = Pattern.compile("\\b(A[^B]*B)\\b");
于 2012-10-11T21:16:14.773 に答える