Negative Lookahead bei regulären Ausdrücken

7

Ich mache regelmäßig Gymnastik. Ich habe es mir zur Aufgabe gemacht, nach C # -Code zu suchen, bei dem der As-Operator nicht verwendet wird und nicht mit einem Null-Check innerhalb einer angemessenen Menge an Speicherplatz. Jetzt möchte ich den C # -Code nicht analysieren. Z.B. Ich möchte Code-Snippets wie

erfassen %Vor%

jedoch nicht erfassen

%Vor%

noch in der Tat

%Vor%

Somit wird jeder zufällige Null-Check als "guter Check" gezählt und daher nicht gefunden.

Die Frage ist: Wie passe ich etwas an, während ich sicherstelle, dass etwas anderes nicht in seiner Umgebung gefunden wird.

Ich habe den naiven Ansatz versucht, nach 'as' zu suchen und dann einen negativen Lookahead innerhalb von 150 Zeichen zu machen.

%Vor%

Der obige reguläre Ausdruck entspricht leider allen obigen Beispielen. Mein Bauchgefühl sagt mir, das Problem ist, dass das nach vorne schauen und dann negative Lookahead viele Situationen finden kann, in denen der Lookahead nicht das '== null' findet.

Wenn ich versuche, den ganzen Ausdruck zu negieren, dann hilft das auch nicht, da dies den meisten C # -Code entsprechen würde.

    
Carlo V. Dango 07.02.2011, 12:41
quelle

6 Antworten

11

Ich liebe Regex-Gymnastik! Hier ist eine kommentierte PHP-Regex:

%Vor%

Und hier ist es in Javascript Stil:

%Vor%

Dieser hat meinen Kopf ein wenig verletzt ...

Hier sind die Testdaten, die ich verwende:

%Vor%     
ridgerunner 16.03.2011, 22:44
quelle
2

Fügen Sie .{1,150} in den Lookahead ein und ersetzen Sie . durch \s\S (im Allgemeinen stimmt . nicht mit Zeilenvorschüben überein). Außerdem kann \b in der Nähe von == irreführend sein.

%Vor%     
robert 07.02.2011 12:49
quelle
2

Ich denke, es würde helfen, den Variablennamen in () zu setzen, damit Sie ihn als Rückverweis verwenden können. Etwas wie das Folgende,

%Vor%     
David Winant 17.03.2011 01:33
quelle
2

Die Frage ist nicht klar. Was genau willst du ? Ich bedauere es, aber ich verstehe es immer noch nicht, nachdem ich die Frage und die Kommentare mehrmals gelesen habe.

.

Muss der Code in C # sein? In Python? Andere ? Zu diesem Punkt gibt es keine Hinweise.

.

Möchten Sie eine Übereinstimmung nur, wenn eine if(... == ...) -Zeile einem Block von var ... = ... -Zeilen folgt?

Oder kann eine heterogene Linie ZWISCHEN dem Block und der if(... == ...) -Zeile stehen, ohne die Übereinstimmung zu stoppen?

Mein Code nimmt die zweite Option als wahr.

.

Stoppt eine if(... == null) -Zeile NACH einer if(... == ...) -Zeile die Übereinstimmung oder nicht?

Ich kann nicht verstehen, ob es Ja oder Nein ist. Ich habe die beiden Regex definiert, um diese beiden Optionen zu erfassen.

.

Ich hoffe, dass mein Code klar genug ist und Ihrer Beschäftigung entspricht.

Es ist in Python

%Vor%

Ergebnis

%Vor%     
eyquem 17.03.2011 13:52
quelle
2

Lassen Sie mich versuchen, Ihr Problem neu zu definieren:

  1. Suchen Sie nach einer "as" -Zuweisung - Sie benötigen wahrscheinlich einen besseren Regex, um nach tatsächlichen Zuweisungen zu suchen und möchten vielleicht den zugewiesenen Ausdruck speichern, aber verwenden wir "\ bas \ b" für jetzt
  2. Wenn Sie if (... == null) innerhalb von 150 Zeichen sehen, stimmen Sie nicht mit
  3. überein
  4. Wenn Sie if (... == null) nicht innerhalb von 150 Zeichen sehen, stimmen Sie mit
  5. überein

Ihr Ausdruck \bas\b.{1,150}(?!\b==\s*null\b) funktioniert wegen der negativen Vorausschau nicht. Die Regex kann immer vor oder hinter einem Buchstaben springen, um diese negative Vorausschau zu vermeiden, und Sie erhalten schließlich eine Übereinstimmung, auch wenn dort ein if (... == null) vorhanden ist.

Regex's sind wirklich nicht gut in nicht passend zu etwas. In diesem Fall sollten Sie versuchen, eine "as" -Zuweisung mit einer "if == null" -Kontrolle innerhalb von 150 Zeichen zu vergleichen:

%Vor%

und negiert dann den Check: if (!regex.match(text)) ...

    
Stephen Chung 22.03.2011 07:03
quelle
1
%Vor%

Ich aktiviere die Option SingleLine mit ?s: . Sie können es in die Optionen Ihrer Regex setzen, wenn Sie möchten. Ich füge hinzu, dass ich \s um as setze, weil ich denke, dass nur Leerzeichen um den as "legal" sind. Du kannst wahrscheinlich \b like

setzen %Vor%

Beachten Sie, dass \s wahrscheinlich Leerzeichen fängt, die keine "gültigen Leerzeichen" sind. Es ist definiert als [\f\n\r\t\v\x85\p{Z}] wobei \p{Z} Unicode-Zeichen in der Kategorie 'Separator, Space' plus Unicode-Zeichen in der Kategorie 'Trennzeichen, Zeile' plus Unicode-Zeichen in der Kategorie 'Separator, Paragraph' .

    
xanatos 23.03.2011 12:39
quelle