Wie funktioniert negatives Lookahead mit Sternchen?

8

Ich versuche zu verstehen, warum ich nicht die erwarteten Ergebnisse von einer Regex bekomme.

Ich weiß schon, was negativ Lookahead ist (anscheinend nicht :-)) Und auch, dass Sternchen Null oder mehrere Male von Wiederholungen ist.

Blick auf diese Regex:

%Vor%

Dies entspricht a , gefolgt von einem non-3 danach.

Wenn man sich diese Testzeichenfolge ansieht, ist der fettgedruckte Teil eine Übereinstimmung:

  

a 3333335

Ok

Auch wenn ich die Regex zu:

ändere %Vor%

Es wird trotzdem übereinstimmen:

  

a 3333335

Dies entspricht a , auf das keine Nicht-3 (mindestens eine)

folgt

Frage

Mein Problem ist mit * :

Lassen Sie uns die Regex zu:

ändern %Vor%

Dies stimmt nicht überein

  

a3333335

Aber meine Frage ist - warum?

Gemäß der Zeichnung:

a sollte nicht folgen: Entweder nichts oder weder Nicht-3s

Aber dies geschieht folgendermaßen: a wird nicht gefolgt von nichts AND wird nicht gefolgt von non3 -s

Warum passt das nicht zusammen?

Und um mein Leben schwieriger zu machen:

Blick auf diese Regex:

%Vor%

Dies wird übereinstimmen:

  

a 3333335

Was ist hier los?

    
Royi Namir 18.09.2015, 21:17
quelle

4 Antworten

6

Das Problem ist, dass ein Stern die leere Zeichenfolge ( "" ) erzeugen kann, und Sie können sagen, dass zwischen jedem Zeichen und der nächsten, es gibt eine leere Zeichenfolge .

Gegeben die Regex:

%Vor%

und du fragst mit a33333 , sagst du mehr oder weniger: lehne ab, wenn es keine oder mehr Wiederholungen von Nicht-3 nach a gibt, aber es gibt solche Wiederholungen: die leere Zeichenfolge, also ohne auch nur eine einzige zu erfassen 3 , wird abgelehnt. Das Matching sieht also so aus:

%Vor%

(Zitate markieren Strings und sind hier keine Zeichen)

Man kann also sagen, dass das negative Lookahead eines regulären Ausdrucks über einem Kleene-Stern immer ablehnen wird (man muss vorsichtig sein, in dem Satz meine ich, dass der Der Kleene-Stern ist über den "gesamten" regulären Ausdruck vereinheitlicht, was bedeutet, dass ein negativer Lookahead, der einen Kleene-Stern enthält, immer zurückweist.

Das Bild zeigt das auch:

Es heißt , wenn nicht gefolgt , es bedeutet, dass es nicht übereinstimmen kann, was in der Box ist. Das Problem ist, dass es kein einzelnes Zeichen braucht, um das Ende der Box zu erreichen.

Dies gilt nicht für a(?![^3]*7) : Hier sagen Sie "* ablehnen, wenn Sie auf null oder mehr nicht-3 gefolgt von einer sieben treffen. Da die Regex [^3]*7 doesn ' t stimmt mit 3333335 überein, der Lookahead wird die Übereinstimmung nicht ablehnen.

    
Willem Van Onsem 18.09.2015, 21:20
quelle
5

Das Problem ist, dass * null oder öfter wiederholen würde. Null Nicht-3s (aka leere Zeichenfolge) enthalten. Nichts bedeutet nicht das Ende der Zeichenfolge , es bedeutet wörtlich nichts (leere Zeichenfolge).

Der Grund, warum das Beispiel mit 7 funktioniert, liegt darin, dass der Lookahead versuchen wird, so viele Nicht-3s wie möglich zu finden. An der Position nach a wäre das null Nicht-3s. Danach wird es versuchen, genau one 7 zu entsprechen. Aber das nächste Zeichen ist 3 , daher wird der Abgleich von a nicht fehlschlagen.

    
ndn 18.09.2015 21:20
quelle
3

Um zu verstehen, warum:

%Vor%

stimmt nicht überein Sie können Ihren Lookahead in

ändern %Vor%

was ebenfalls fehlschlägt und der Grund ist, dass Ihre Lookahead Assertion, dass a nicht von irgendetwas gefolgt werden muss, einschließlich einer leeren Zeichenfolge, immer false zurückgibt, daher wird Ihre Regex immer scheitern .

2. Regex ist das:

%Vor%

was erfolgreich ist, weil es wirklich keine 0 oder mehr von non-3 gefolgt von 7 in Ihrer Eingabe gibt.

Wenn Sie Ihre Eingabe z. a7 , dann wird die Übereinstimmung fehlschlagen.

    
anubhava 18.09.2015 21:28
quelle
0

Das Problem ist, dass sich das * genauso verhält wie anderswo.

[^ 3] * stimmt mit jeder Zeichenfolge überein, weil sie mit "so viele wie 3, wie möglich einschließlich keiner" übereinstimmt.

a (?! [^ 3] * 7) Stimmt mit "any" überein, gefolgt von so vielen Nicht-Dreien wie möglich, einschließlich keiner und einer "7". " was äquivalent zu "any 'a' ist, gefolgt von einer 7, es sei denn, sie sind durch '3's' getrennt.

    
user1958756 18.09.2015 21:48
quelle

Tags und Links