Ich weiß, dass Java-Regex Lookbacks unterschiedlicher Länge nicht unterstützt und dass das Folgende einen Fehler verursachen sollte
%Vor%, aber wenn das * durch einen Spezifizierer mit fester Länge als solcher ersetzt wird
%Vor%es schlägt immer noch fehl. Warum ist das?
Sie dachten also, dass Java kein unendliches Lookbehind unterstützt?
Aber das folgende Muster wird kompiliert!
%Vor%... obwohl es in einem Match All zu unerwarteten Ergebnissen führt (siehe Demo ).
Andererseits kannst du mit Erfolg diesen anderen unendlichen Lookbehind verwenden (was ich auf dieser Frage mit großer Überraschung gefunden habe)
%Vor% um diese Zeichenfolge zu teilen: 0,123,45,6789,4,5,3,4,6000
Es wird korrekt ausgegeben (siehe Online-Demo ):
%Vor%Diesmal sind die Ergebnisse das, was Sie erwarten.
Aber wenn Sie die Regex das geringste Bit anpassen, um Paare statt Triplets mit (?<=\G\d+,\d+),
zu erhalten, wird dieses Mal nicht geteilt (siehe die Demo ).
Java Lookbehind ist notorisch fehlerhaft. Wenn ich das weiß, empfehle ich Ihnen Verschwenden Sie keine Zeit zu versuchen zu verstehen, warum es etwas tut Das ist undokumentiert.
Die entscheidenden Worte, die mich vor einiger Zeit zu dieser Schlussfolgerung geführt haben, sind die von Jan Goyvaerts, der Co-Autor von The Regex Cookbook und einem arch-regex-guru ist, der ein grandioses erschaffen hat Regex-Engine und muss für sein Debugging-Tool RegexBuddy:
auf den meisten Regex-Aromen unter der Sonne bleibenJava hat eine Reihe von Fehlern in seiner Lookbehind-Implementierung. Einige (aber nicht alle) davon wurden in Java 6 behoben.
Im Folgenden finden Sie einige Testfälle (ich entfernte die redundanten Parens, wie von @Pshemo erwähnt). Es schlägt nur dort fehl, wo das Lookbehind eine Subalternation enthält. Der Fehler ist
%Vor%"Offensichtlich" ist das Schlüsselwort hier.
%Vor%Ausgabe:
%Vor%java regex unterstützt Lookbacks unterschiedlicher Länge nicht
Es ist nicht völlig richtig, Java unterstützt begrenzte Look-Behinds variabler Länge, Beispiel (?<=.{0,1000})
ist erlaubt oder so etwas wie (?<=ab?)c
oder (?<=abc|defgh)
.
Aber wenn es überhaupt kein Limit gibt, unterstützt Java es nicht.
Also, was ist nicht offensichtlich für die Java-Regex-Engine für ein Lookbehind-Submuster:
Ein {m,n}
-Quantifikator, der auf ein Untermuster ohne feste Länge angewendet wurde:
Um diese Fehlermeldung in dieser speziellen Art von Fällen zu erhalten, benötigen Sie zwei Kriterien:
ein Untermuster mit potentiell variabler Länge (dh: das einen Quantor, eine Alternation oder eine Rückreferenz enthält)
und ein {m,n}
Typ-Quantifizierer.
All diese Fälle scheinen für den Benutzer nicht offensichtlich zu sein, da es wie eine willkürliche Wahl erscheint. Ich denke jedoch, dass der eigentliche Grund darin besteht, die Voranalysezeit des Musters durch die Regex-Motorübertragung zu begrenzen.