Suche Hilfe für RegExp - SuchSyntax

  • Hallo Autoit Gemeinde!

    Ich bin gerade dabei per Autoit einen kleinen Formelinterpreter zu schreiben, der in erster Linie mal einen String nach Vaiablen durchsucht und Operanten filtert.
    ...In einen zweiten Moment wird er dann auch berechnet...

    Diese Strings mit Formeln würde so ähnlich aussehen:

    local $String = "IF D>=50 THEN 3 ELSE 8"

    in dem Fall, würde das Script in einem separaten Variablenarray, nach Variable "D" suchen, und dessen Wert z.B. "20" in der Formel mit der Variable tauschen.
    Das Ganze wird in ein Array geschrieben und später weiterverarbeitet.

    So Weit So gut.

    nun kommt aber der Haken:
    bei einem "=" gibt es leider mehrere Möglichkeiten, da ein "=" auch in einem ">=", "=>" und "==" vorkommen kann, gibt es hier einen Fehler.
    Das selbe Problem habe ich auch mit folgenden Operatoren : ">", "<", ">=", "=>", "<=", "=<".

    leider gibt es dazu noch folgende Schreibweisen, die ich auch nicht unterbinden kann, da diese Formelstrings aus einem externen Programm kommen.
    Also einmal mit und einmal ohne Leerstellen, die dann auch an jeder Stelle stehen können.

    D = 50
    D= 50
    D =50

    oder

    D>=50
    D >=50
    D >= 50
    D>= 50
    ....

    ich brächte hier eine Regex Syntax, die Explizit nach dem jeweiligen Operator sucht, egal ob der mit Leerzeichen von der Variable getrennt ist, oder nicht.
    Nur leider höhrt hier meine Logik bezüglich RegEx auf und ich habe keinen Plan, wie man das anstellen sollte...

    Kann mir vielleicht jemand helfen?

    hier mein bisheriges Script...


    Spoiler anzeigen


    #include <Array.au3>


    local $Pipe, $sSyntax, $aDelim, $aParts
    local $sFormel
    $sFormel = "IF D => 50 THEN 1 ELSE 2"
    ;~ $sFormel = "IF D=>50 THEN 1 ELSE 2"
    ;~ $sFormel = "IF D<= 50 THEN 1 ELSE 2"
    ;~ $sFormel = "IF D <=50 THEN 1 ELSE 2"
    ;~ $sFormel = "IF D=50 THEN 1 ELSE 2"
    ;~ $sFormel = "IF D=50 THEN 1 ELSE 2"


    $Pipe = "|" ;Trennzeichen für Syntax
    $sSyntax = "\bIF\b" & $Pipe
    $sSyntax = $sSyntax & "\bTHEN\b" & $Pipe
    $sSyntax = $sSyntax & "\bELSE\b" & $Pipe
    $sSyntax = $sSyntax & "\bAND\b" & $Pipe
    $sSyntax = $sSyntax & "\bOR\b" & $Pipe
    $sSyntax = $sSyntax & "\bXOR\b" & $Pipe
    $sSyntax = $sSyntax & "\bNOT\b" & $Pipe
    $sSyntax = $sSyntax & "COS[\\(]" & $Pipe
    $sSyntax = $sSyntax & "TAN[\\(]" & $Pipe
    $sSyntax = $sSyntax & "SIN[\\(]" & $Pipe
    $sSyntax = $sSyntax & "ARCSIN[\\(]" & $Pipe
    $sSyntax = $sSyntax & "ARCCOS[\\(]" & $Pipe
    $sSyntax = $sSyntax & "ARCTAN[\\(]" & $Pipe
    $sSyntax = $sSyntax & "EXP[\\(]" & $Pipe
    $sSyntax = $sSyntax & "LN[\\(]" & $Pipe
    $sSyntax = $sSyntax & "MOD[\\(]" & $Pipe
    $sSyntax = $sSyntax & "PREC[\\(]" & $Pipe
    $sSyntax = $sSyntax & "ABS[\\(]" & $Pipe
    $sSyntax = $sSyntax & "[\\)]" & $Pipe ;Klammer zu ")"
    $sSyntax = $sSyntax & "\b=\b" & $Pipe
    $sSyntax = $sSyntax & "\b<\b" & $Pipe
    $sSyntax = $sSyntax & "\b>\b" & $Pipe
    $sSyntax = $sSyntax & "<=" & $Pipe ;suche ohne Trennstring (kann auch ohne Leerzeichen an einer Variable hängen
    $sSyntax = $sSyntax & "=>" & $Pipe ;suche ohne Trennstring (kann auch ohne Leerzeichen an einer Variable hängen
    $sSyntax = $sSyntax & ">=" & $Pipe ;suche ohne Trennstring (kann auch ohne Leerzeichen an einer Variable hängen
    $sSyntax = $sSyntax & "<>" & $Pipe ;suche ohne Trennstring (kann auch ohne Leerzeichen an einer Variable hängen
    $sSyntax = $sSyntax & "[+]" & $Pipe
    $sSyntax = $sSyntax & "[-]" & $Pipe
    $sSyntax = $sSyntax & "[:;?@*/^]" ;alle Mathematischen Operanten zwischen zwei Werten


    $aDelim = StringRegExp($sFormel, $sSyntax, 3 ); Extrahiert die Syntax aus der Formel und schreibt die Werte in den String
    _ArrayDisplay($aDelim)
    ;~ MsgBox("","", $aDelim)

  • Also, ein Pattern, was alle eventuellen Operatoren matcht, ist ja nicht so schwer, denke ich:
    ((?:(?:<|>)?=(?:<|>)?)|>|<)
    Sieht zwar kompliziert aus, ist aber eigentlich ganz einfach. Wenn wirklich nur nach Operatoren gesucht werden soll, war's das. Ansonsten müsste man zum Einbinden halt noch ein \s* oder so vor und hinter das Subpattern setzen.

    Edit:
    Ah, ich hatte eine Erleuchtung, glaube ich. Du siehst "=" wahrscheinlich nicht als Operator an, oder? Und ich habe oben auch "==" vergessen.
    Mein Pattern oben kannst du dir hier live anschauen: Klick
    Wenn du allerdings "=" ausschließen möchtest, dann kannst du dieses Pattern verwenden: ((?:(?:<|>)=?)|(?:=(?:<|>))|==)

    Zu finden hier: Klick