Allgemeine Frage zu RegExp

  • Hallo liebe AutoIt Community. Ich wollte mich auch mal in das Thema reguläre Ausdrücke einarbeiten. Nachdem ich ein sehr gutes (so war meine Empfindung) Tutorial durchgearbeitet habe, wollte ich mal etwas "Praxiserfahrung" sammeln. Ich wollte mir also einen RegExp erstellen, der verschiedene Daten in unterschiedlichen Formaten erfassen soll. Meine Liste iste von Daten ist die folgende:

    Ich habe mir dann diesen RegExp gebastelt.

    Zitat

    ((([0-2][1-9])|(3[0-1]))|(\b[1-9]))\.(((0[1-9])|(1[0-2]))|([1-9]))\.((\d{4}\b)|(\d{2}\b))


    Laut meinem RegExBuddy sowie dem Online-RegEx-Tester werden auch nur die richtigen Daten gefunden, aber sobald ich versuche mir die Treffer in AutoIt anzuzeigen, lauf ich vor ne Wand.

    Hier das Script, mit dem ich es probiert habe.

    [autoit]

    #include <Array.au3>
    $String = "34.05.2009"&@CRLF&"19.14.1887"&@CRLF&"16.04.1990"&@CRLF&"01.01.1900"&@CRLF&"7.5.08"&@CRLF&"1.10.1900"&@CRLF&"31.5.08"&@CRLF&"40.13.09"&@CRLF
    $Matches = StringRegExp($String,"((([0-2][1-9])|(3[0-1]))|(\b[1-9]))\.(((0[1-9])|(1[0-2]))|([1-9]))\.((\d{4}\b)|(\d{2}\b))",1)
    _ArrayDisplay($Matches)

    [/autoit]

    Ihr seht ja selbst was dabei rauskommt - Jedenfalls nicht das, was ich raushaben möchte.
    Könnt ihr mir sagen was ich falsch mache?

  • Du möchtest quasi _Dateisvalid in sämtlichen Formatsvarianten als Regexp? Nur damit man auch weiss was dein Ergebnis sein soll.

    Dein Input ist jetzt der ganze "String" geprüft soll aber jede Zeile einzeln werden:

    [autoit]


    #include <Array.au3>
    $String = "34.05.2009"&"|"&"19.14.1887"&"|"&"16.04.1990"&"|"&"01.01.1900"&"|"&"7.5.08"&"|"&"1.10.1900"&"|"&"31.5.08"&"|"&"40.13.09"
    $split = StringSplit($String, "|")
    _ArrayDisplay($split)
    for $i = 1 to $split[0]
    $Matches = StringRegExp($split[$i],"((([0-2][1-9])|(3[0-1]))|(\b[1-9]))\.(((0[1-9])|(1[0-2]))|([1-9]))\.((\d{4}\b)|(\d{2}\b))",1)
    _ArrayDisplay($Matches)
    next
    exit

    [/autoit]


    So siehts schon besser aus :)
    Am Pattern muss noch was gedreht werden.

  • Erstmal danke euch beiden
    @ blubbstar
    Ja mit der Flag 3 hab ich es auch schon probiert, allerdings sah das Ergebnis auf den ersten Blick genauso unbefriedigend wie mit Flag 1.
    Jetzt bei näherer Betrachtung sehe ich zumindest, dass die richtigen Daten gefunden werden. Allerdings gefällt mir die Formatierung innerhalb des Arrays nicht - viele SubPatterns treten doppelt auch und es gibt viele leere Arrayfelder.

    nuts
    Genau das habe ich vor. Deine Variante gibt ja eigenltich das selbe aus wie Flag 3 nur halt in mehreren Arrays. Außerdem kann ich ja nicht immer, wenn ich einen RegEx über einen String laufen lassen will, den String in hunderte Arrayelemente aufteilen. Es sollte ja doch eigentlcih auch mit einem einzelnen String funktionieren.

    Wie müsste ich das ganze umschreiben damit mir immer die Rot makierten (also korrekten) Daten angezeigt werden?
    Meine Vorstellung wäre gewesen, dass ich am Ende einen Array habe a la

    Zitat

    5
    16.04.1990
    01.01.1900
    7.5.08
    1.10.1900
    31.5.08

    Was müsst ich da am script / an der Pattern drehen, damit das rauskommt?
    Mein RegExbuddy zeigt mir nämlich genau das was ich haben will ( siehe bild unten)

  • Hm was habt ihr denn da für tolle Progs.? Demnach stimmt das Pattern.

    Noch ein versuch zu später Stunde.

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    $String = "34.05.2009"&"|"&"19.14.1887"&"|"&"16.04.1990"&"|"&"01.01.1900"&"|"&"7.5.08"&"|"&"1.10.1900"&"|"&"31.5.08"&"|"&"40.13.09"
    $split = StringSplit($String, "|")
    global $sreturn
    ;_ArrayDisplay($split)
    for $i = 1 to $split[0]
    $Matches = StringRegExp($split[$i],"((([0-2][1-9])|(3[0-1]))|(\b[1-9]))\.(((0[1-9])|(1[0-2]))|([1-9]))\.((\d{4}\b)|(\d{2}\b))",2)
    if IsArray($Matches) then $sreturn &= $Matches[0] &"|"
    next
    $sreturn = StringTrimRight($sreturn, 1)
    $areturn = stringsplit($sreturn, "|")
    MsgBox(1, "",$sreturn)
    _ArrayDisplay($areturn)

    [/autoit]

    edit \ Rückgabe noch etwas angepasst.

    2 Mal editiert, zuletzt von nuts (22. November 2009 um 23:37)

  • Danke Nuts, du hast mir den Schubser in die richtige Richtung gegeben. Man sollte auch mal die Hilfe aufschlagen.

    Zitat

    Return an array of arrays containing global matches including the full match


    Ich verwende nun Flag 4, mit dem folgenden Script

    [autoit]

    #include <Array.au3>
    $String = "34.05.2009"&@CRLF&"19.14.1887"&@CRLF&"16.04.1990"&@CRLF&"01.01.1900"&@CRLF&"7.5.08"&@CRLF&"1.10.1900"&@CRLF&"31.02.1990"&@CRLF&"31.5.08"&@CRLF&"40.13.09"&@CRLF

    [/autoit][autoit][/autoit][autoit]

    $Matches = StringRegExp($String,"((([0-2][1-9])|(3[0-1]))|(\b[1-9]))\.(((0[1-9])|(1[0-2]))|([1-9]))\.((\d{4}\b)|(\d{2}\b))",4)

    [/autoit][autoit][/autoit][autoit]

    Dim $eAr
    Dim $Return[1] = [0]

    [/autoit][autoit][/autoit][autoit]

    For $i = 0 to UBound($Matches)-1
    $eAr = $Matches[$i]
    _ArrayAdd($Return,$eAr[0])
    Next
    $Return[0] = UBound($Return)-2
    _ArrayDisplay($Return)

    [/autoit]

    So funzt das für mich perfekt, und ich bin auch noch stolz, weil ich meinen Willen durchgesetzt habe (Kein splitten des Ursprünglichen Strings)
    Nochmals vielen vielen dank für deine Mühen!

  • Mit _ArrayAdd haste jetzt eben die Redim-Bremse (um die ich mich, zugegeben wenig elegant, rumgemogelt habe) doch eingebaut.
    Du könntest auch das return Array mit UBound($Matches) -1 deklarieren, befüllen und anschließend einmal Redimen.
    Oder so ein Stringgebastel (das geht bestimmt noch besser ...).

    P.S. Der Regexbuddy ist ja cool 8o

  • Danke für den Tip. Ich denk so selten an Redim ^^
    Ich habs jetzt so gelöst:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    $String = "34.05.2009"&@CRLF&"19.14.1887"&@CRLF&"16.04.1990"&@CRLF&"01.01.1900"&@CRLF&"7.5.08"&@CRLF&"1.10.1900"&@CRLF&"31.02.1990"&@CRLF&"31.5.08"&@CRLF&"40.13.09"&@CRLF
    $Matches = StringRegExp($String,"((([0-2][1-9])|(3[0-1]))|(\b[1-9]))\.(((0[1-9])|(1[0-2]))|([1-9]))\.((\d{4}\b)|(\d{2}\b))",4)
    Dim $eAr, $Return[UBound($Matches)]
    For $i = 0 to UBound($Matches)-1
    $eAr = $Matches[$i]
    $Return[$i] = $eAr[0]
    Next
    $Return[0] = UBound($Return)-1
    _ArrayDisplay($Return)

    [/autoit]

    Und jap, der RegExBuddy hat mich auch sofort überzeugt ^^
    BugFix hat den mal irgendwann in der Shoutbox erwähnt, und da hab ich den mal vorsorglich besorgt ^^