Nach dem Blick auf den Pattern
Code und versuchen, es zu verfolgen, bin ich davon überzeugt, dass dies nur ein Fehler ist. Beide Beispiele sollten zu einer Ausnahme führen. Aber die Logik, die dafür testet, ist falsch.
Dieser Code erscheint in ein paar Plätze:
temp = info.maxLength * cmax + maxL;
info.maxLength = temp;
if (temp < maxL) {
info.maxValid = false;
}
Beachten Sie, dass solange maxLength
und cmax
nicht negativ sind, temp
sollte nie weniger als maxL
es sei denn, Überlauf aufgetreten ist. maxValid
wird schließlich vom Lookbehind-Code verwendet; Wenn maxValid
false
ist, wird "look-behind group does not have obvious maximum length error"
geworfen.
Von dem, was ich in einem regex wie < prefix>< Ausdruck kann sagen>{m,n}
, in dem obigen Code ist info.maxLength
die maximale Länge der "Expression", cmax
die obere Grenze des Quantors ist, und maxL
ist die maximale Länge von "Präfix". Wenn ein Quantifizierer *
oder +
ist, wird die obere Grenze auf Integer.MAX_VALUE
festgelegt.(Alle Variablen sind hier int
.) Dies bedeutet, dass es einen Überlauf geben wird, es sei denn, info.maxLength
ist 1 und maxL
ist 0. Das ist genau der Fall mit
(?<=a*)bc
da das Muster mit der quantifier Länge hat 1, und es gibt nichts, vor dem a*
was bedeutet maxL
0 sein wird, das ist, warum dieser Fall fällt durch die Ritzen.
Für alle anderen Werte wird die Berechnung überlaufen, aber das bedeutet nicht notwendigerweise temp < maxL
wird wahr. Wenn info.maxLength
gerade ist, wird eine Ausnahme ausgelöst. aber wenn info.maxLength
ungerade ist, wird das Muster kompiliert, wenn maxL
klein genug ist. Dies ist aufgrund der Art und Weise wie Wraparound funktioniert, mathematisch; Der Code, der versucht, auf einen Überlauf zu prüfen, ist ziemlich fehlerhaft. Das bedeutet, dass
(?<=a*)bc // succeeds
(?<=(ab)*)bc // throws exception
(?<=(abc)*)bc // succeeds
(?<=(abcd)*)bc // throws exception
(?<=(abcde)*)bc // succeeds
auch:
(?<=xa*)bc // throws exception
(?<=x(abc)*)bc // succeeds
Hinweis: Es sollte in Ihrem Beispiel regex zu beachten, Lookbehind ist nutzlos:
(?<=a*)bc
Das Lookbehind zu testen, sagt, ob Der aktuellen Position geht kein oder mehrmaliges Vorkommen des Buchstabens a
voraus. Das ist immer wahr, trivial. Der Lookbehind hat also keinen Sinn. In ähnlicher Weise
(?<=a+)bc
entspricht
(?<=a)bc
da, solange es ein a
ist die aktuelle Position der vorhergehenden, spielt es keine Rolle, wie viele es sein könnte. Das gleiche gilt für all Beispiele, die, mit Ausnahme von dieser nicht eine Ausnahme:
(?<=x(abc)*)bc // succeeds
da hier die Matcher gehen haben nach hinten gesucht abc
‚s in der Zeichenfolge und sicherstellen, dass die letzten Vorangegangen ist x
. Es scheint, dass Pattern
in diesem Fall eine Ausnahme auslösen sollte, aber wegen der fehlerhaften Überlaufprüflogik ist dies nicht der Fall. Daher bin ich unsicher, ob es tatsächlich das richtige Ergebnis zurückgeben würde oder ob es abstürzen oder in eine Endlosschleife geraten könnte. Ich habe es jedoch nicht ausprobiert.
Wirklich, sollte der Code nur direkt prüfen, ob cmax
zu Integer.MAX_VALUE
gleich ist, statt es in der Berechnung mit und den Code der Hoffnung, kann später sagen, dass das Ergebnis gefälscht ist.
(Hinweis: Dies wird nicht von der JLS, sondern von der Bibliotheksdokumentation angegeben.) –
Die [Bibliotheksdokumentation] (http://docs.oracle.com/javase/8/docs/api/java/util/regex /Pattern.html) spezifiziert es auch nicht wirklich. Es verweist auf ein O'Reilly-Buch, das das spezifische Verhalten beschreibt. – ajb
Danke. Ich habe die Korrektur vorgenommen. –