![]() |
CSV Parser (wieder mal)
Hallo zusammen,
Um es kurz zu machen: Kennt jemand einen CSV Parser (Delphi Klasse) der dies kann: Beispielzeile (Delimiter=';'): Dies geht;"Dies muss auch";"Auch dies;ist möglich"; Ausgabe: -Dies geht -Dies muss auch (oder "Dies natürlich auch") -Auch dies;ist möglich (oder "Auch dies;ist möglich") Die Datei muss ich einlesen und in eine Datenbank speichern. Die Texte werden aus verschiedenen Systemen automatisiert in eine Excel Datei geschrieben. Ich erhalte dann jeweils den CSV Export der im Extremfall in einzelnen "Zellen" obige Werte haben kann. Dann lade ich die Datei in einen Stream und dann in eine TStrings Klasse (LoadFromStream) da ich diese nicht exlusiv öffnen kann. Bis hier ist alles noch im grünen Bereich. Aber danach.. Gruss Werner |
Re: CSV Parser (wieder mal)
Eventuell
![]() |
Re: CSV Parser (wieder mal)
Also wenn man sich nur mal estwas aus der System.pas mopst und etwas umbaut, dann dürfte es so auch gehen.
Nun sollte man sich nur noch schnell die Funktionen etwas passender um und fertig :angel2:
Delphi-Quellcode:
nur die Zeilen muß man dann noch selber einlesen :roll:
function GetParamStr(P: PChar; var Param: string): PChar;
var i, Len: Integer; Start, S: PChar; begin // U-OK while True do begin while (P[0] <> #0) and (P[0] <> ';') do Inc(P); if (P[0] = '"') and (P[1] = '"') then Inc(P, 2) else Break; end; Len := 0; Start := P; while (P[0] <> #0) and (P[0] <> ';') do begin if P[0] = '"' then begin Inc(P); while (P[0] <> #0) and (P[0] <> '"') do begin Inc(Len); Inc(P); end; if P[0] <> #0 then Inc(P); end else begin Inc(Len); Inc(P); end; end; SetLength(Param, Len); P := Start; S := Pointer(Param); i := 0; while (P[0] <> #0) and (P[0] <> ';') do begin if P[0] = '"' then begin Inc(P); while (P[0] <> #0) and (P[0] <> '"') do begin S[i] := P^; Inc(P); Inc(i); end; if P[0] <> #0 then Inc(P); end else begin S[i] := P^; Inc(P); Inc(i); end; end; Result := P; end; function ParamCount(const S: String): Integer; var P: PChar; S2: string; begin // U-OK Result := 0; P := PChar(S); while True do begin P := GetParamStr(P, S2); if S2 = '' then Break; Inc(Result); end; end; function ParamStr(const S: String; Index: Integer): string; var P: PChar; begin P := PChar(S); while True do begin Dec(Index); P := GetParamStr(P, Result); if (Index = 0) or (Result = '') then Break; end; end; end; |
Re: CSV Parser (wieder mal)
Hallo,
Danke Euch beiden, Den Link von Daniel G werde ich Morgen anschauen. Allerdings müsste ich dann ziemlich viel ändern. Das von himitsu wäre mir symphatischer. Allerdings muss ich gestehen dass ich da momentan nicht durchsteige :oops: Wo kann ich da meine Zeile übergeben? Gruss Werner |
Re: CSV Parser (wieder mal)
es sollte genauso funktionieren, wie
![]() ![]() (das GetParamStr ist nur eine Hilfsfunktion) Zeile irgendwie aus Datei auslesen ParamStr(S, 2) ergibt en 3. Wert (Zählung mit 0 beginnend) PS: in der CodeLib gibt es auch noch Explode, aber ich glaub die Originalversion behandelt kein " eventuell hilft ja sowas:
Delphi-Quellcode:
S = eine Zeile
Function Explode2(Const S: String): TStringDynArray;
Var i: Integer; Begin SetLength(Result, ParamCount(S)); For i := 0 to High(Result) do Result[i] := ParamStr(S, i); End; |
Re: CSV Parser (wieder mal)
Hallo,
ich nutze seit Delphi4 dieses Tool..mir reicht es und ist einfach. [c] iss nicht von mir aber Freeware!!!!
Delphi-Quellcode:
Anwendung..auch ganz einfach
unit MyParser;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; type TMyParser = class(TComponent) private FieldSep: char; FLine: string; NumFields: byte; Index, Ct: array[0..255] of integer; function Getstr(n: byte): string; constructor Create( AParent : TComponent ); override; public property Sepchar: char read FieldSep write FieldSep; property count: byte read NumFields; property fields[n: byte]: string read Getstr; default; procedure Parse(const Line: string); end; procedure Register; implementation constructor TMyParser.Create( AParent : TComponent ); begin inherited Create(aParent); FieldSep:=' '; FLine:=''; NumFields:= 0; end; function TMyParser.Getstr(n: byte): string; begin result := ''; if n > NumFields then exit; if n = 0 then result := FLine else if n > 0 then begin dec(n); {0-based arrays!} if Index[n] > 0 then result := copy(FLine, index[n], ct[n]); end; end; procedure TMyParser.Parse(const line: string); var i,p : byte; s: string; s2 : string; begin Fline := Line; s:= line; NumFields := 0; i := pos(FieldSep, s); while i > 0 do begin s2 := copy (s,1,i -1); if NumFields = 0 then index[NumFields] := 1 else index[NumFields] := pos(s2,fline); ct[NumFields] := length(s2); delete(s,1,i); i := pos(FieldSep, s); inc(NumFields); end; end; procedure Register; begin RegisterComponents('Parser', [TMyParser]); end; end.
Delphi-Quellcode:
hoffe, hilft Dir :-D
MyParser1.sepchar := ';';
MyParser1.parse(s); for i := 1 to MyParser1.count do ListBox1.items.add(MyParser1.fields[i]); |
Re: CSV Parser (wieder mal)
Alles was dafür notwendig ist, kann bereits TStringlist.
Einfach die Einstellungen richtig setzen und LoadfromFile oder LoadFromStream benutzen. |
Re: CSV Parser (wieder mal)
Zitat:
Wie würdest Du denn die Anforderung aus meinem ersten Post mit TStringlist lösen? Delimiter:=';' und QuotChar:='"'; funktioniert nämlich nicht falls Du dass meinst. Denn dann Trennt TStringlist bei Leerzeichen wenn keine Quote's vorhanden sind. Oder hab ich was verpasst? @Daniel G. : Dein Link funktioniert. Danke. @Himitsu : Deine Variante natürlich ebenfalls. Danke. @Kaktus: Deine Variante hab ich nicht ausprobiert aber aus der Distanz scheint der Spezialfall damit nicht abgedeckt zu sein. Gruss Werner |
Re: CSV Parser (wieder mal)
Zitat:
|
Re: CSV Parser (wieder mal)
Stimmt :oops:
Neun Jahre Delphi und keine Kenntnis von StrictDelimiter! Wieder was gelernt. Sorry |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:29 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz