Tag Leute...
ich verzweifle jetzt schon seit Tagen. Ich möchte aus eine .txt Datei, die ungefähr so aussieht,
[Blockierte Grafik: http://abload.de/img/unbenanntsjs3o.png]
nur dir Nummern 1 - 3 auslesen. Ich dachte, das könnte ich mit StringRegExp machen. Leider hatte im damit bis zu diesem Zeitpunkt noch nicht viel am Hut...
Und selbst nach Tage check ich's nicht...
Kann mir da einer helfen?
.txt Tabelle(?) - StringRegExp?
-
Schnieker -
22. Dezember 2015 um 17:44 -
Erledigt
-
-
Hey Schnieker,
warum denn Stringregexp? Das sieht doch super formatiert aus. Sind das Tabs? Dann genügt es doch die .txt-Datei mit FileReadToArray in ein Array zu lesen.
Local $aArray = FileReadToArray(@ScriptDir & "\___.txt"). Da ergibt sich doch schon direkt:
$aArray[0][1] = Nummer 1
$aArray[0][2] = Nummer 2
$aArray[0][3] = Nummer 3Oder ist der Aufbau doch anders?
-
Leider nicht. Es ist einfach nur ein Text mit vielen Leerzeichen und Zeilenumbrüchen. Eventuell hab ich mich auch falsch ausgedrückt...
[Blockierte Grafik: http://abload.de/img/unbenannt1lszz.png]
Ich möchte als erstes auslesen was in Zeile 1 bei Nummer 1 steht. Dann was in Zeile 1 bei Nummer 2 steht und dann was in Zeile 1 bei Nummer 3 steht.
Dann geh' ich in Zeile 2. und immer so weiter. Ich hoffe das kann man jetzt verstehen -
- Offizieller Beitrag
Statt eines Screenshots solltest Du lieber eine Beispieldatei posten.
Problematisch wird aber das trennen der einzelnen Blöcke/Nummern, weil im Block 2 auch Leerzeichen vorkommen.
Du musst also herausfinden, wie Du Block 2 und Block 3 eindeutig identifizieren kannst.
Gibt es in Block 3 ebenfalls Leerzeichen? Ist im Block 3 immer ein Slash vorhanden? Irdendetwas eindeutiges halt. -
Ja, eine Beispieldatei würde helfen. (Die unterschiedlich großen Abstände sehen aber schon stark nach Tabs aus). Wenn das so ist, wäre der Feldtrenner ja eindeutig.
-
Per StringSplit zeilenweise durchgehen und dort die einzelnen Spalten per StringMid rausholen.
Die Spalten scheinen ja alle eine feste breite zu haben. -
@AspirinJunkie
Danke! Das klappt! Spitze! -
Ja, eine Beispieldatei würde helfen. (Die unterschiedlich großen Abstände sehen aber schon stark nach Tabs aus). Wenn das so ist, wäre der Feldtrenner ja eindeutig.
Und wenn es mehrer Leerzeichen sind dann eine Schleife mit "Ersetze zwei Leerzeichen" durch "ein Leerzeichen" solange es "zwei Leerzeichen" gibt, wenn nicht NEXT. Und dann StringSplitt. Müßte doch so gehen. Das nun um diese Uhrzeit in die Praxis umsetzen und das so wie ich hier gerade sitze? Nee, lieben dann doch nicht.
-
Sollte nicht funktionieren, da Leerzeichen ja auch innerhalb von Spalten vorkommen (siehe 2. Spalte).
Und dort sollte demnach nicht getrennt werden.Die Ausgabe hier sieht klassisch nach C-printf() aus (also StringFormat in AutoIt).
Die Umkehrung dessen wäre dann sowas wie scanf.
Wenn ich Zeit finde schreibe ich vielleicht mal ein entsprechendes Pendant für AutoIt (falls es nicht schon existiert). -
So ich hatte kurz Zeit.
Hier mal ne kleine Funktion welche die Verarbeitung solcher Stringtabellen etwas vereinfachen könnte:AutoIt
Alles anzeigen#include <Array.au3> $s_String = " 1 sinnlos links rechts 13,00€ " & @CRLF & _ " 10 sinnlos irgendwas irgendwas 12,00€" & @CRLF & _ @CRLF & _ " 20 sinnlos blabla blabla 16,30€" ConsoleWrite($s_String & @CRLF) $a_Data = String_HandleTable($s_String, "int 4; void 8; leftString 10; rightString 12; Euro 8") _ArrayDisplay($a_Data, "parsed") ; Beispiel wie man auch eine UDF zum parsen einzelner Spalten nutzen kann Func Euro(Const $s_String) Return Number(StringReplace($s_String, ",", ".", 0, 1)) EndFunc ;==>Euro Func String_HandleTable(ByRef Const $s_String, Const $s_Format) ; by AspirinJunkie ; create format array Local $a_Split = StringRegExp($s_Format, '\s*(\w+)\s*(\d+)', 4) If @error Then Return SetError(1, @error, "") Local $a_Cols[UBound($a_Split)][3] Local $x = 1, $j = 0 For $i In $a_Split $x += $i[2] If $i[1] = "void" Then ContinueLoop $a_Cols[$j][0] = $i[1] $a_Cols[$j][1] = $x - $i[2] $a_Cols[$j][2] = $i[2] $j += 1 Next If $j <> UBound($a_Cols) Then ReDim $a_Cols[$j][3] ; process string Local $a_Split = StringRegExp($s_String, "([^\r\n|\n|\r]+)", 3) Local $a_Ret[UBound($a_Split)][UBound($a_Cols)] Local $s_rawVal, $s_Val $x = 0 For $s_Line In $a_Split For $i = 0 To UBound($a_Cols) - 1 $s_rawVal = StringMid($s_Line, $a_Cols[$i][1], $a_Cols[$i][2]) If $a_Cols[$i][0] = "leftString" Then $s_Val = StringStripWS($s_rawVal, 2) ElseIf $a_Cols[$i][0] = "rightString" Then $s_Val = StringStripWS($s_rawVal, 1) Else $s_Val = Execute($a_Cols[$i][0] & '("' & $s_rawVal & '")') If @error Then ContinueLoop EndIf $a_Ret[$x][$i] = $s_Val Next $x += 1 Next Return $a_Ret EndFunc ;==>String_HandleTable
Die Funktion bekommt den zu parsenden String und eine Angabe wie eine einzelne Zeile aufgebaut ist.
Hierbei gibt man einen Funktionsnamen an mit welcher die Spalte geparst werden soll (z.B. int wenn es eine Ganzzahl ist oder String bei Strings).
Dabei gibt es 3 spezielle Bezeichner: leftString für linksbündige Strings (entfernt nachfolgende Leerzeichen), rightString (entfernt vorherige Leerzeichen) und void wenn man die Spalte für die Ausgabe ignorieren möchte.
Nach dem Funktionsnamen nur noch die Breite der Spalte (Anzahl Zeichen) und fertig.
Am Beispiel sieht man denke ich ganz gut wie es gemeint ist.