Parsen mit Rexx?

(DE) System, Installation, Konfiguration, Hardware, Treiber, Netzwerk, Virtualisierung, etc.
(EN) System, Installation, Configuration, Hardware, Drivers, Network, Virtualisation, etc.
Antworten
Benutzeravatar
DonLucio
Beiträge: 1080
Registriert: So 29. Dez 2013, 01:14
Wohnort: Hamburg
Kontaktdaten:

Parsen mit Rexx?

Beitrag von DonLucio »

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
Andi B.
Beiträge: 814
Registriert: Di 24. Dez 2013, 16:40
Kontaktdaten:

Beitrag von Andi B. »

WORDPOS?
SUBSTR(string, WORDPOS(';' , string) ... oder ähnlich?

Nicht getestet. Und ich bin kein REXX Experte...
ArcaOSNewcomer
Beiträge: 51
Registriert: Mo 4. Nov 2024, 18:28

Beitrag von ArcaOSNewcomer »

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.
Benutzeravatar
DonLucio
Beiträge: 1080
Registriert: So 29. Dez 2013, 01:14
Wohnort: Hamburg
Kontaktdaten:

Beitrag von DonLucio »

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.
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.

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;
Damit hätte man ein Array (Rexx-Sprech: Stem), das man variabel abarbeiten kann.

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.
erdmann
Beiträge: 631
Registriert: Mo 4. Jan 2016, 14:36

Beitrag von erdmann »

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 ...
Benutzeravatar
DonLucio
Beiträge: 1080
Registriert: So 29. Dez 2013, 01:14
Wohnort: Hamburg
Kontaktdaten:

Beitrag von DonLucio »

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 ...
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.

Aber für Windows-User wäre es vermutlich die einzige Opton :D

Gruß,
Lutz W.
Michael
Beiträge: 10
Registriert: Sa 28. Dez 2013, 20:46

Beitrag von Michael »

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

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
Michael
Benutzeravatar
DonLucio
Beiträge: 1080
Registriert: So 29. Dez 2013, 01:14
Wohnort: Hamburg
Kontaktdaten:

Beitrag von DonLucio »

Hallo Michael,
Michael hat geschrieben: Sa 26. Jul 2025, 07:32 Es sind mehr Zeilen.
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.
Antworten