Frage Java Regex-Muster, das das erste Auftreten von "Grenze" nach einer beliebigen Zeichenfolge abgleicht


Ich möchte ein Muster festlegen, das eine Fanggruppe findet, die durch das erste Auftreten der "Grenze" begrenzt ist. Aber jetzt wird die letzte Grenze verwendet.

Z.B.:

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 + ">");
}

Drucke:

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

und ich möchte, dass es gedruckt wird:

"Match = <A to the first B>"

Was muss ich innerhalb des Musters ändern?


11
2017-10-11 21:12


Ursprung


Antworten:


Mach dein *  nicht geizig / widerwillig verwenden *?:

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

Standardmäßig verhält sich das Muster gierig und passt so viele Zeichen wie möglich an, um das Muster zu erfüllen, dh bis zum letzten B.

Sehen Widerwillige Quantifier von die Dokumente, und dieses Tutorial.


35
2017-10-11 21:14



Verwenden Sie keinen gierigen Ausdruck für die Übereinstimmung, z.

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

5
2017-10-11 21:14



* ist ein gieriger Quantifizierer, der so viele Zeichen wie möglich abgleicht, um das Muster zu erfüllen. Bis zum letzten B Auftreten in Ihrem Beispiel. Deshalb müssen Sie einen widerwilligen verwenden: *?, das wird so wenige Charaktere wie möglich machen. Also sollte dein Muster leicht verändert werden:

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

Siehe "widerwillige Quantifizierer" in die Dokumente, und dieses Tutorial.


4
2017-10-11 22:01



Vielleicht expliziter als das * widerwillig / faul wäre zu sagen, dass du nach A suchst, gefolgt von einer Menge Sachen, die das sind ist kein B, gefolgt von B:

Pattern ptrn = Pattern.compile("\\b(A[^B]*B)\\b");

1
2017-10-11 21:16