Seltsames Problem mit '(. *) *', '(. *) +', '(. +) *' in Java regex

8

Um das Problem wie in einer kürzlich gestellten Frage zu reproduzieren - Warum macht (. *) * zwei Übereinstimmungen und wählt nichts in der Gruppe $ 1 aus? Ich habe verschiedene Kombinationen von * und + , innerhalb und außerhalb der Klammern und der Ergebnis wurde ich nicht erwartet.

Ich hätte die Ausgabe erwartet, genauso wie eine, die in der angenommenen Antwort in dieser Frage erklärt wurde, und auch in einer anderen doppelten Frage, getaggt unter Perl - Warum nimmt das. * Nicht die gesamte Zeichenfolge in diesem Perl-Regex auf? . Aber es verhält sich nicht so.

Um es einfach zu machen, hier ist der Code, den ich versucht habe: -

%Vor%

Und das ist die Ausgabe, die ich für alle 4 Kombinationen erhalten habe: -

%Vor%

Nun, was ich nicht verstehe, warum in 1st und 2nd output, ich bekomme nicht die gesamte Zeichenfolge als first result für matcher.find() . Ich meine, idealerweise sollte im ersten Fall .* zuerst den gesamten String erfassen und dann am Ende auch empty string erfassen. Nun, obwohl es das erwartete Ergebnis für die zweite Übereinstimmung liefert, verhält es sich nicht gut für 1st match .

Und im zweiten Fall sollte ich nicht einmal die zweite Übereinstimmung erhalten, weil ich einen + Quantor außerhalb der Klammer habe.

Meine erwartete Ausgabe ist: -

%Vor%

Warum habe ich in der 3rd -Ausgabe null als zweite Übereinstimmung anstelle von empty string erhalten? Sollte das 2. Spiel für die erste 3 Kombination nicht gleich sein?

Die vierte Ausgabe entspricht den Erwartungen. Also, kein Zweifel daran.

    
Rohit Jain 24.01.2013, 11:58
quelle

1 Antwort

7

Sie sehen den Effekt des gleichen Phänomens, das Sie in der Frage sehen, mit der Sie verknüpft sind:

Für (.*)* :

  • Das erste matcher.start() ist 0 , weil hier die Übereinstimmung ( "input" ) beginnt.
  • Die erste matcher.group(1) ist "" , weil die wiederholte (.*) die eingefangene "input" mit der leeren Zeichenfolge überschrieben hat (aber matcher.group(0) enthält input" ).
  • Die zweite matcher.start() ist 5 , da sich die Regex-Engine nach der ersten erfolgreichen Übereinstimmung befindet.
  • Das zweite matcher.group(1) (sowie matcher.group(0) ) ist "" , weil das alles war, was am Ende des Strings gefunden wurde.

Für (.*)+ ist es dasselbe. Schließlich kann die leere Zeichenfolge beliebig oft wiederholt werden und immer noch die leere Zeichenfolge sein.

Für (.+)* erhalten Sie null , denn während die zweite Übereinstimmung erfolgreich ist (null Wiederholungen einer Zeichenkette der Länge 1 stimmt mit der leeren Zeichenkette überein), konnten die einfangenden Klammern nichts erfassen, daher ist der Inhalt null (wie in undefined, anstelle der leeren Zeichenfolge).

    
Tim Pietzcker 24.01.2013, 12:04
quelle

Tags und Links