Stringregexp und Pattern

  • Hallo Zusammen,


    ich habe folgendes Problem. Ich habe eine txt Datei mit Kundendaten aus der ich Informationen auslesen und in einer Gui darstellen will. das funktoniert auch alles soweit mit filereadline. Nur manchmal ist das Format der txr anders, weil z.b. ein Postfach hinzukommt oder ein Name der Firma, also verschieben sich die Reihen und mit filrereadline klappt dann nix mehr. Ich will die Datei mit Stringregexp und Pattern durchsuchen und jedsmal den Eintrag bekommen, z..b von Kunde oder Strasse, weil sich die Beschreibungen nie verändern, nur die Reihe. Aber jedesmal bekomme ich dann nur die 1, als Match gelifert, Auch wenn ich Flag 1 nehme, bekomme ich nicht den vollen Datensatz zurück.

    Gibt es eine Möglichkeit mit Stringregexp die Reihe herauszufinden in der das Wort am Anfang vorkommt, denn ich will noch die Reihe Splitten und nur bestimmte Werte erhalten.

    • Offizieller Beitrag

    Bitte hänge deinen Code nicht als Datei an (so viel ist es ja nicht) sondern poste ihn hier mit Tags [ spoiler][ autoit]Dein Skript[ /autoit][/spoiler] (ohne Leerzeichen in den Tags).

    Und ein Datensatz reicht nicht als Muster, wir brauchen die unterschiedlichen. Du sagst ja mal steht mehr drin.
    Und gib genau an, welche Daten du benötigst.

  • include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    $KD = FileReadLine("0815.txt",1)
    $KD1 = StringSplit($KD," ")
    $Str = FileReadLine("0815.txt",2)
    $Str1 = StringSplit($Str," ")
    $Ort = FileReadLine("0815.txt",3)
    $rnr = FileReadLine("0815.txt",5)
    $dateb = FileReadLine("0815.txt",8)
    $dateb1 = StringReplace($dateb," ",",")
    $dateb2 = StringSplit($dateb1,",")
    $Bestell = FileReadLine("0815.txt",10)
    $Bestell1 = FileReadLine("0815.txt",11)
    $dateg = FileReadLine("0815.txt",14)
    $dateg1 = StringReplace($dateg," ",",")
    $dateg2 = StringSplit($dateg1,",")
    $gelie = FileReadLine("0815.txt",16)
    $gelie1 = FileReadLine("0815.txt",17)
    $Form1 = GUICreate("Form1", 498, 386, 192, 124)
    $Kunde = GUICtrlCreateLabel($KD1[1]&" "&$KD1[2], 56, 88, 387, 17)
    $Strasse = GUICtrlCreateLabel($Str1[1]&" "&$Str1[2], 56, 112, 387, 17)
    $Ort = GUICtrlCreateLabel($Ort, 56, 136, 387, 17)
    $Rufnummer = GUICtrlCreateLabel($rnr, 56, 160, 387, 17)
    $BestellLabel = GUICtrlCreateLabel("Bestellungen vom " & $dateb2[2], 56, 200, 250, 17)
    $Bestellungen = GUICtrlCreateLabel($Bestell &" "& $Bestell1, 56, 224, 193, 105)
    $geliefertlabel = GUICtrlCreateLabel("Geliefert am "& $dateg2[2], 272, 200, 180, 17)
    $Geliefert = GUICtrlCreateLabel($gelie &" "& $gelie1, 272, 216, 177, 113)
    $Infolabel = GUICtrlCreateLabel("Information über den Kunden", 104, 32, 314, 33)
    GUICtrlSetFont(-1, 18, 400, 0, "MS Sans Serif")
    GUISetState(@SW_SHOW)
    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    EndSwitch
    WEnd


    Hier die txt, welche Postfach und Firma enthält. Die Lines stimmern dann nicht mehr, aber Einträge Kunde, Strasse usw, bleiben gleich

  • Hab jetzt einfach mal ALLES ausgelesen:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    Global $sText

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

    _Text()

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

    $aKundeninfo = StringRegExp($sText, "(?i)(?:Kunde\s+(.+)\r\n)(?:Firma\s+(.+)\r\n)?(?:Strasse\s+(.+)\r\n)?(?:Ort\s+(.+)\r\n)?(?:Postfach\s+(.+)\r\n)?(?:Vorwahl\s+(.+)\r\n)?(?:Rufnummer\s+(.+)\r\n)?", 3)
    ;~ _ArrayDisplay($aKundeninfo)
    For $i = 0 To UBound($aKundeninfo) - 1 Step 7
    MsgBox(0, "", _
    $aKundeninfo[$i + 0] & @CRLF & _
    $aKundeninfo[$i + 1] & @CRLF & _
    $aKundeninfo[$i + 2] & @CRLF & _
    $aKundeninfo[$i + 3] & @CRLF & _
    $aKundeninfo[$i + 4] & @CRLF & _
    $aKundeninfo[$i + 5] & @CRLF & _
    $aKundeninfo[$i + 6] _
    )

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

    $aBestellung = StringRegExp($sText, "Kunde\s+(" & $aKundeninfo[$i] & ")[\w\W]+?Bestellung\r\nDatum (.+)\r\nProdukte([\w\W]+?)(?=Geliefert)Geliefert\r\nDatum (.+)\r\nProdukte([\w\W]+?)(?=Kunde|\Z)", 3)
    _ArrayDisplay($aBestellung)
    Next

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

    Func _Text()
    $sText = _
    "Kunde Max Mustermann" & @CRLF & _
    "Firma autoit" & @CRLF & _
    "Strasse Fragenzeichen xy" & @CRLF & _
    "Ort nirgendwo" & @CRLF & _
    "Postfach 0850" & @CRLF & _
    "Vorwahl 0190" & @CRLF & _
    "Rufnummer 110" & @CRLF & _
    "" & @CRLF & _
    "Bestellung" & @CRLF & _
    "Datum 04.4.2010" & @CRLF & _
    "Produkte" & @CRLF & _
    "1 x Holz" & @CRLF & _
    "2 x Fliesen" & @CRLF & _
    "" & @CRLF & _
    "Geliefert" & @CRLF & _
    "Datum 06.04.2010" & @CRLF & _
    "Produkte" & @CRLF & _
    "2x Fliesen" & @CRLF & _
    "1x Holz" & @CRLF & _
    "" & @CRLF & _
    "Kunde Max Musterfrau" & @CRLF & _
    "Strasse Fragenzeichen xyz" & @CRLF & _
    "Ort überall" & @CRLF & _
    "Vorwahl 01805" & @CRLF & _
    "Rufnummer 112" & @CRLF & _
    "" & @CRLF & _
    "Bestellung" & @CRLF & _
    "Datum 14.4.2010" & @CRLF & _
    "Produkte" & @CRLF & _
    "2 x Laminat" & @CRLF & _
    "3 x Eis" & @CRLF & _
    "" & @CRLF & _
    "Geliefert" & @CRLF & _
    "Datum 16.04.2010" & @CRLF & _
    "Produkte" & @CRLF & _
    "2x Laminat" & @CRLF & _
    "3x Eis"
    EndFunc ;==>_Text

    [/autoit]
    • Offizieller Beitrag

    Deine Beschreibung ist ziemlich dürftig. Gibt es bloß einen Kunden pro Datei?

    Wenn ja, dann vielleicht so:

    Spoiler anzeigen
    [autoit]


    $sDaten = FileRead(@ScriptDir & '\0815v2.txt')
    $sKunde = StringRegExpReplace($sDaten, '(?s).*Kunde\t*(.+?)\r.*', '$1')
    $sFirma = StringRegExpReplace($sDaten, '(?s).*Firma\t*(.+?)\r.*', '$1')
    $sStrasse = StringRegExpReplace($sDaten, '(?s).*Strasse\t*(.+?)\r.*', '$1')
    $sOrt = StringRegExpReplace($sDaten, '(?s).*Ort\t*(.+?)\r.*', '$1')
    MsgBox(0, 'Kundendaten', $sKunde & @CR & $sFirma & @CR & $sStrasse & @CR & $sOrt)

    [/autoit]
  • Ja Super, dass klappt. Es geht mir weniger um ein vollkommenes Skript, sondern mehr darum wie ich den Befehl formulieren muss. Ich habe verschieden TXT dateien, aus denen ich immer Kunde, Strasse, und Ort ,usw. angezeigt werden will. Da die txt unterscheidlich sind und ich nicht auf feste Lines zurückgreifen kann, hat das nie geklappt. Aber mit deinen Skript funktioniert es.


    $sKunde = StringRegExpReplace($sDaten, '(?s).*Kunde\t*(.+?)\r.*', '$1')


    Bist du so nett mit den Befehl zu erklären? Was bewirkt (?s).*Kunde\t*(.+?)\r.*', '$1' und warumFileRead(@ScriptDir & '\0815v2.txt')

    Bin erst seit ner Woche mit AutoIT dran, deshalb fehlen mir noch die Kenntnisse verkürzt und pro zu schreiben.

  • Gibt es keinen Befehl, der in der txt datei erkennt in welcher Reihe das Wort vorkommt, damit ich dann die Reihe in ein Var packen kann, um später mit StringSplit zu arbeiten. Oder gibt es eine Möglichkeit allen Strings von einem Wort bis zu nächsten zu erfassen. An meinem Beispiel also alles zwischen Bestellung und Geliefert, weil manche Kunden, haben mehr bestellt und somit gibt es mehr Reihen.

  • Da Oscar nicht da ist, und ich langeweile habe:

    Wenn dich RegExp interessiert - http://www.google.de/search?q=StringRegExp+Tutorial

  • Also fileread nimmt er weil man mit fileread die gesamte datei in eine variable einlesen kann.
    d.h. in $sDaten steht die gesamte alles was auch in der textdatei steht

    alle strings besser gesagt den string weil es nur einer ist kannst du mit _StringBetween ermitteln

    • Offizieller Beitrag

    Statt SubPattern wird die oft das Wort Backreferenz begegnen. Du kannst immer selbst für Teile des Matches Backreferenzen erzeugen, indem du den betreffenden Teil in Klammern setzt. Diese Backreferenzen werden der Reihe nach numeriert und können so direkt angesprochen werden ($1..$9).

  • Danke für eure schnellen Antworten, ich werde es mal mit String between versuchen....

    Scheint, als wenn ich noch Wochen brauche, alles so schnell zu kapieren wie Ihr

    • Offizieller Beitrag

    Gibt es keinen Befehl, der in der txt datei erkennt in welcher Reihe das Wort vorkommt, damit ich dann die Reihe in ein Var packen kann, um später mit StringSplit zu arbeiten. Oder gibt es eine Möglichkeit allen Strings von einem Wort bis zu nächsten zu erfassen. An meinem Beispiel also alles zwischen Bestellung und Geliefert, weil manche Kunden, haben mehr bestellt und somit gibt es mehr Reihen.

    Es gibt auch noch den Befehl "StringInStr". Damit kannst Du in einem String (der geladenen Textdatei) nach einem anderen String (z.B. "Bestellung") suchen lassen. Als Ergebnis erhälst Du die Position des Suchstrings.
    Dann suchst Du noch nach "Geliefert" und schon hast Du die beiden Positionen und kannst den dazwischenliegenden Text mit StringMid extrahieren.