Parsen mit Rexx?
Parsen mit Rexx?
Problem: Wie parse ich Sätze einer CSV-Datei, die als Trenner ';' verwendet?
Ganz allgemein:
Um die einzelnen Bestandteile eines variabel langen Strings in einzelne Variable aufzuspalten gibt es imho in Rexx nur die WORD() und SUBWORD()-Funktionen. Das PARSE VALUE variable WITH var1 ... taugt nicht besonders gut für variable lange Strings.
Die Funktionen der WORD()-Familie haben aber alle das Problem, grundsätzlich nur auf Space (Blank, Leerstelle) zu erkennen. Damit scheitere ich aber bei Sätzen einer CSV-Datei. Diese sind typischerweise TAB- oder ';'-getrennt.
Ich würde mir wünschen, dass es bei der WORD()-Funktion einen zweiten Parameter gibt, der das Trennzeichen bezeichnet. Nein, gibt's nicht: Ein Wort ist immer blank-getrennt vom nächsten Wort.
Ich könnte zwar mit translate() alle ';' zu <space> umwandeln und dann mit WORD() und WORDS() die Sätze dynamisch abarbeiten. Das geht aber nicht, wenn die Sätze der CSV-Datei Blanks innerhalb eines ';'-getrennten Feldes anthalten.
Ich muß also irgendwie mit dem PARSE VALUE-Statement zurechtkommen. Nun gut, das ist kein Hexenwerk, ein Dreizeiler tut den Job. Aber eleganter fände ich eine Funktion, die direkt meinen Trenner als Parameter aufnmmt, wie z.B. die explode()-Funktion in PHP.
Meine Frage wäre also: Habe ich velleicht etwas (ein Rexx-Feature) übersehen?
Danke,
Lutz Wagner
Ganz allgemein:
Um die einzelnen Bestandteile eines variabel langen Strings in einzelne Variable aufzuspalten gibt es imho in Rexx nur die WORD() und SUBWORD()-Funktionen. Das PARSE VALUE variable WITH var1 ... taugt nicht besonders gut für variable lange Strings.
Die Funktionen der WORD()-Familie haben aber alle das Problem, grundsätzlich nur auf Space (Blank, Leerstelle) zu erkennen. Damit scheitere ich aber bei Sätzen einer CSV-Datei. Diese sind typischerweise TAB- oder ';'-getrennt.
Ich würde mir wünschen, dass es bei der WORD()-Funktion einen zweiten Parameter gibt, der das Trennzeichen bezeichnet. Nein, gibt's nicht: Ein Wort ist immer blank-getrennt vom nächsten Wort.
Ich könnte zwar mit translate() alle ';' zu <space> umwandeln und dann mit WORD() und WORDS() die Sätze dynamisch abarbeiten. Das geht aber nicht, wenn die Sätze der CSV-Datei Blanks innerhalb eines ';'-getrennten Feldes anthalten.
Ich muß also irgendwie mit dem PARSE VALUE-Statement zurechtkommen. Nun gut, das ist kein Hexenwerk, ein Dreizeiler tut den Job. Aber eleganter fände ich eine Funktion, die direkt meinen Trenner als Parameter aufnmmt, wie z.B. die explode()-Funktion in PHP.
Meine Frage wäre also: Habe ich velleicht etwas (ein Rexx-Feature) übersehen?
Danke,
Lutz Wagner
WORDPOS?
SUBSTR(string, WORDPOS(';' , string) ... oder ähnlich?
Nicht getestet. Und ich bin kein REXX Experte...
SUBSTR(string, WORDPOS(';' , string) ... oder ähnlich?
Nicht getestet. Und ich bin kein REXX Experte...
-
- Beiträge: 51
- Registriert: Mo 4. Nov 2024, 18:28
Oder Du wandelst vorher alle echten Leerzeichen in ein Steuerzeichen, was im Text nicht vorkommt (z. B. #). Dann kannst Du das Semikolon zum "Trennzeichen blank" machen und WORD() benutzen.
Ja, das würde wohl funktionieren. Problem dabei wäre nur, solch ein Zeichen zu finden (in deinem beispiel '#'). Das könnte sich in der Praxis, wo es große und auch periodisch wiederkehrende CSV-Dateien zu verarbeiten gäbe, als schwierig herausstellen. Und genau das ist der Fall in meiner Anwendung (Online-Banking): Ich kriege jeden Monat die Journale von insgesamt 4 Konten zum Download angeboten, und ich brauche die CSV-Version (anstatt PDF), weil ich die Journale intern bei mir weiterverarbeten möchte.ArcaOSNewcomer hat geschrieben: Do 24. Jul 2025, 03:23 Oder Du wandelst vorher alle echten Leerzeichen in ein Steuerzeichen, was im Text nicht vorkommt (z. B. #). Dann kannst Du das Semikolon zum "Trennzeichen blank" machen und WORD() benutzen.
Mein Workaround wäre:
Code: Alles auswählen
do i=1 While Rec > ""
parse value Rec with Fields.i ";" Rec;
end;
Fields.0 = i-1;
Meine Frage in diesem Thread war eigentlich auch nur, ob ich zum Thema Parsen irgendwie eine Wissenslücke habe, vor allem in Bezug auf das Fehlen eines optionalen Parameters in der WORDS()-Funkton (etwa ";" statt dem impliziten " "). Das scheint aber offenbar nicht der Fall zu sein.
Danke an alle "Lückensucher"

Lutz W.
Weiß nicht ob das einfacher ist, aber kannst du nicht die .CSV Dateien in OpenOffice importieren und dann ein Makro schreiben, was die Daten verarbeitet ? Unter Excel ginge das sicherlich, meine Hoffnung wäre, dass OpenOffice das auch kann.
Ist natürlich auch Aufwand und man muss sich in die Makrosprache von OpenOffice einlesen ...
Ist natürlich auch Aufwand und man muss sich in die Makrosprache von OpenOffice einlesen ...
Ich vermute mal, dass dieses Excel-Maro deutlich umfangreicher wäre als mein "Dreizeiler" (ok, es sind 4 Zeilen). Zumal die Einbettung von OpenCalc in meinen Workflow, der mit Lesen von 4 Dateien beginnt, sie dann in Bezug auf diverse Felder verarbeitet und anschließend noch sortiert und als 1 Datei ausgibt, kaum möglich wäre.erdmann hat geschrieben: Fr 25. Jul 2025, 09:30 ... in OpenOffice importieren und dann ein Makro schreiben, was die Daten verarbeitet ?
Ist natürlich auch Aufwand und man muss sich in die Makrosprache von OpenOffice einlesen ...
Aber für Windows-User wäre es vermutlich die einzige Opton

Gruß,
Lutz W.
Hallo Lutz
Es sind mehr Zeilen.
Zeile: ist die Eingelesene Zeile mit ";" als Trenner
mit pos suchst Du das nächste ";" ab Beginn
mit substr schreibst Du alles zwischen Beginn und Ende in Spalte.i
ist kein ";" mehr vorhanden wird der rest übernommen und beendet
Michael
Es sind mehr Zeilen.
Zeile: ist die Eingelesene Zeile mit ";" als Trenner
mit pos suchst Du das nächste ";" ab Beginn
mit substr schreibst Du alles zwischen Beginn und Ende in Spalte.i
ist kein ";" mehr vorhanden wird der rest übernommen und beendet
Code: Alles auswählen
Zeile = "Natur- und Landschaftsführer; Technisches Büro; Lieferservice; ISAnhalt; Fenster-Türen-Rolladen; Heimwerkerprofi"
Beginn = 1
do i=0
b = pos(";",Zeile,Beginn)
if b = 0 then do
i = i + 1
Spalte.i = substr(Zeile,Beginn)
say i Spalte.i
leave
end
Ende = b - Beginn
Spalte.i = substr(Zeile,Beginn,Ende)
say Spalte.i
Beginn = b + 2
end
Hallo Michael,
Nochmal zur Erinnerung: Ziel meines Posts war nicht, einen Workaround zu finden. sondern ich wollte mich nur vergewissern, dass es tatsächlich keine Option bei der WORDS()-Funktion gibt, die das Blank durch ein ";" (oder anderes wahlfreies Trennzeichen) ersetzen läßt.
Dem scheint nun tatsächlich so zu sein.
Gruß
Lutz W.
Ja, aber so geht's sicherlich auch.
Nochmal zur Erinnerung: Ziel meines Posts war nicht, einen Workaround zu finden. sondern ich wollte mich nur vergewissern, dass es tatsächlich keine Option bei der WORDS()-Funktion gibt, die das Blank durch ein ";" (oder anderes wahlfreies Trennzeichen) ersetzen läßt.
Dem scheint nun tatsächlich so zu sein.
Gruß
Lutz W.