RegExp - Finde wenn Klammern ausbalanciert

  • Du bist mein Held der Woche! :rock: Dein neues Pattern funktioniert wie gewünscht, die Leerzeilen werden entfernt.

    Dein Pattern übersteigt meine RegExp Fähigkeiten zwar um etwa 2 "Fähigkeitsklassen", aber mit all den Informationen blicke ich ein wenig durch. Ich habe dein neues Pattern minimal geändert, sodass das Leerzeichen hinter der (ausbalancierten) schließenden Klammer erhalten bleibt.

    Dein neues Pattern aus dem letzen Post und darunter meine Mini-Änderung:

    (?mi)^\h*Func\h+((?(DEFINE)(?<brackets>\((?|''(?>[^'']+|'''')*''|"(?>[^"]+|"")*"|[^\(\)\r\n"'']*|(?&brackets))*\)))\w+\h*(?&brackets)(?=\h*\R\h*EndFunc))

    (?mi)^\h*Func\h+((?(DEFINE)(?<brackets>\((?|''(?>[^'']+|'''')*''|"(?>[^"]+|"")*"|[^\(\)\r\n"'']*|(?&brackets))*\)))\w+\h*(?&brackets)\h*(?=\R\h*EndFunc))

    Im Test funktioniert es, aber das heißt ja nicht unbedingt, dass es immer so funktioniert. Deshalb die Frage: Ist das so richtig, oder hat das noch andere Auswirkungen?

    Vielen Dank für deine Mühe! :thumbup:

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Im Test funktioniert es, aber das heißt ja nicht unbedingt, dass es immer so funktioniert. Deshalb die Frage: Ist das so richtig, oder hat das noch andere Auswirkungen?

    Ne das passt super. Das (positive) Lookbehind (das (?=...) wirkt im Grunde so: behandele den Teil ganz normal aber lasse ihn nicht Teil des Matches werden. Daher kannst du (wie du es ja gemacht hast) damit die Leerzeichen Teil des Matches werden lassen oder eben nicht.

  • Funktion StringRegExp

    (?=X) Positiv Folgend: Findet, wenn das Untermuster X an der aktuellen Abfrageposition übereinstimmt.

    Das (positive) Lookbehind (das (?=...) wirkt im Grunde so: behandele den Teil ganz normal aber lasse ihn nicht Teil des Matches werden.

    Vielen Dank für diese Erklärung! Oben die Erklärung aus der AutoIt Hilfe. Ganz ehrlich, die Hilfe zu StringRegExp sollte überarbeitet werden. Deine Erklärung finde ich viel verständlicher. 8)

    So, dann seh'n wir mal, was wir draus machen. :saint:

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Als erstes: Meine Erklärung war falsch da ich mal wieder lookbehind mit lookahead verwechselt habe.
    Das (?=...) ist das positive lookahead!

    Streng genommen schaut es ob an der aktuellen Stelle noch das direkt folgt was du im lookahead angibst.

    Also das was davor steht wird nur gematcht wenn das dahinter folgt.

    Diese Definition ist dann verständlicher und die bessere wenn man die anderen lookarounds (positive/negative lookbehind/ahead) im Gesamten betrachtet.

    Denn das negative lookahead ((?!...)) lässt sich eigentlich nur so erklären dass das was vor dem lookbehind kommt gematcht wird, wenn das im lookahead eben gerade nicht folgt.

  • Meine Erklärung war falsch da ich mal wieder lookbehind mit lookahead verwechselt habe.

    Meine heile Welt liegt in Scherben ... ;(8o

    Streng genommen schaut es ob an der aktuellen Stelle noch das direkt folgt was du im lookahead angibst.

    Also das was davor steht wird nur gematcht wenn das dahinter folgt.

    Schon besser, meine Welt fängt wieder an zu heilen! :saint:

    Jetzt schwirrt mir der Kopf, muss ich erstmal verdauen. :)

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Professor Bernd 23. Juli 2020 um 21:21

    Hat den Titel des Themas von „RegExp - Nicht-finden, wenn nach Suchbegriff noch was kommt“ zu „RegExp - Finde wenn Klammern ausbalanciert“ geändert.
  • AspirinJunkie

    Es haben sich Bugs gezeigt.

    Das Problem scheint mit unbalancierten Quotes zu tun zu haben, die auch eine oder mehrere Zeilen vorher auftreten können. Mehrere Pattern haben einen Teil, der nur findet, wenn das Gesuchte NICHT in Quotes steht. Bei den einfacheren Pattern konnte ich ein \R einsetzen, was Abhilfe geschaft hat für das Problem der fehlenden Quotes vor und hinter Klammern (Screenshot). Aber das Monster-Pattern aus Posting #21 habe ich nicht hingekriegt (Screenshot - vermischen von Funktionen).

    Mein Workaround mit \R

    '(?x)( (?>"(?> [^"]+ | "" )*" | ''(?> [^'']+ | '''' )*'') (*SKIP)(*FAIL) |...

    '(?x)( (?>"(?> [^"]+ | "" )*" | ''(?> [^'']+ | '''' )*'')\R (*SKIP)(*FAIL) |...

    Im Demo-Script: Einmal in Zeile 153 und einmal in Zeile 183.

    Im Anhang ist ein Demo-Script mit deinem Pattern aus Posting #21 und eine Test-Datei bei der die Bugs aufgetreten ist. Das Demo Script enthält noch nicht meinen Workaround, damit die Voraussetzungen nicht verfälscht werden.

    Ich vermute, das Problem hat mit den von dir erwähnten lookarounds zu tun. Kann man die Suche nach unbalancierten Quotes so begrenzen, dass sie nur innerhalb 1 Zeile gewertet werden?

    Edit: Im Demo-Script werden für besseres Debugging die @CRLFs im Ausgabe-Fenster als Zeichenfolge CRLF angezeigt.

  • Kann man die Suche nach unbalancierten Quotes so begrenzen, dass sie nur innerhalb 1 Zeile gewertet werden?

    Klar:

    Code
    (?mi)^\h*Func\h+((?(DEFINE)(?<brackets>\((?|''(?>[^''\v]+|'''')*''|"(?>[^"\v]+|"")*"|[^\(\)\r\n"'']*|(?&brackets))*\)))\w+\h*(?&brackets)\h*(?=\R\h*EndFunc))

    Edit: Evtl. wichtig dazu zu sagen: Das ist das Pattern für den String in AutoIt, da die Hochkommas bereits esaped sind.

    Einmal editiert, zuletzt von AspirinJunkie (24. Juli 2020 um 18:12)