Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   CSV / ASCII-Delimited (https://www.delphipraxis.net/184713-csv-ascii-delimited.html)

p80286 16. Apr 2015 13:23

CSV / ASCII-Delimited
 
Hallo zusammen,
ichg habe eine .CSV-Datei erhalten, die nicht ganz "normgerecht" ist. Und zwar hat sie das folgende Format:
Code:
"feld1";"Feld2";"Feld3" [CRLF]
"feld1";"Feld2";"Feld3"[CRLF]
"feld1";"Feld2";"Feld3" [CRLF]
....
In einigen zeilen folgt also auf das " noch ein Leerzeichen, und dann erst das CRLF als Zeilenende. Wären die Felder nicht durch " begrenzt wäre es klar, das Leerzeichen gehört dazu. Da aber RFC4180 nur so von "may" wimmelt hätte ich gerne Eure Meinung zur korrekten Behandlung der Daten.
(Excel und Calc lesen das Leerzeichen übrigens mit)

Gruß
K-H

Bernhard Geyer 16. Apr 2015 13:40

AW: CSV / ASCII-Delimited
 
Frag doch den ersteller der CSV-Datei was damit gemacht werden soll

Sir Rufo 16. Apr 2015 13:42

AW: CSV / ASCII-Delimited
 
Da RFC4180 explizit von Comma-Separeted-Values spricht, ist das per se schon nicht normgerecht :stupid:

Aber darauf ist dann auch gesch...en (mit ein bisserl Transferleistung).

Es wird sich dort leider nicht explizit dazu ausgelassen, ob ein Leerzeichen zulässig ist oder nicht und wenn ja, wie es behandelt werden soll.

Meine Vermutung ist allerdings, dass die Intention war, dass es nicht zulässig ist und die Schreibweise einfach nur unglücklich ist.

Statt
Code:
  1.   Each record is located on a separate line, delimited by a line
       break (CRLF). For example:

       aaa,bbb,ccc CRLF
       zzz,yyy,xxx CRLF
hätten die schreiben sollen
Code:
  1.   Each record is located on a separate line, delimited by a line
       break (CRLF). For example:

       aaa,bbb,ccc<CRLF>
       zzz,yyy,xxx<CRLF>
Denn sonst könnte man dort sogar ein Leerzeichen als zwingend vorgeschrieben ansehen.

Das die Intention war dort kein Leerzeichen zuzulassen, kann man hier raus erarbeiten
Code:
The ABNF grammar [2] appears as follows:

   file = [header CRLF] record *(CRLF record) [CRLF]

   header = name *(COMMA name)

   record = field *(COMMA field)

milos 16. Apr 2015 13:57

AW: CSV / ASCII-Delimited
 
Vielleicht hilft dir das hier weiter:
Geschrieben für D7

Delphi-Quellcode:
// Deklarationen
Lines : array of TStrings;
procedure ReadCSV(AStrings : TStrings);

// Funktionen
procedure TForm1.ReadCSV(AStrings: TStrings);
var
  InString : boolean;

  CurrentLineIndex : integer;
  CurrentLine : string;

  CurrentCharIndex : integer;
  CurrentChar : char;

  StringBuffer : string;

  LLine : TStrings;
begin
  InString := False;
  StringBuffer := '';

  for CurrentLineIndex := 0 to AStrings.Count-1 do
  begin
    CurrentLine := AStrings[CurrentLineIndex];
    StringBuffer := '';
    LLine := TStringList.Create;

    for CurrentCharIndex := 1 to Length(CurrentLine) do
    begin
      CurrentChar := CurrentLine[CurrentCharIndex];

      if (not(InString)) and
         (CurrentChar = ' ') then
        Continue
      else if (not(InString)) and
              (CurrentChar = '"') then
      begin
        InString := true;
        Continue;
      end
      else if (InString) then
      begin
        if CurrentChar = '"' then
        begin
          LLine.Add(StringBuffer);
          InString := false;
          StringBuffer := '';
          Continue;
        end;
      end;

      if (not(InString)) and
         (CurrentChar = ';') then
        Continue;

      StringBuffer := StringBuffer + CurrentChar;

      if StringBuffer = '[CRLF]' then
      begin
        SetLength(Lines,Length(Lines)+1);
        Lines[Length(Lines)-1] := LLine;
        Break;
      end;
    end;
  end;
end;

procedure TForm1.btn1Click(Sender: TObject);
var
  LStrings : TStrings;
begin
  LStrings := TStringList.Create;
  LStrings := mmo1.Lines;
  ReadCSV(LStrings);
  ShowMessage(Lines[0][0]);
  ShowMessage(Lines[1][0]);
  ShowMessage(Lines[1][2]);
  ShowMessage(Lines[2][1]);
  ShowMessage(Lines[2][2]);
end;

Sir Rufo 16. Apr 2015 14:01

AW: CSV / ASCII-Delimited
 
@milos

Wenn es Unstimmigkeiten / unterschiedliche Lesarten der RFC4180 gibt, wie willst du dann einen Code schreiben, der exakt nach RFC4180 agiert?

Es geht hier nicht um irgendeinen Code sondern um das was die RFC4180 aussagt und ob die Daten nun RFC4180 konform sind oder nicht.

Wenn ich mit jemandem ausmache, dass er mir die Daten nach RFC4180 liefern soll, dann haue ich dem das so lange um die Ohren, bis es so ankommt wie RFC4180 das vorschreibt. Dazu müssen aber alle Beteiligten die RFC4180 gleich verstehen/lesen

taveuni 16. Apr 2015 14:02

AW: CSV / ASCII-Delimited
 
Und was ist das Problem an der Ausgangsfrage?

milos 16. Apr 2015 14:04

AW: CSV / ASCII-Delimited
 
Zitat:

Zitat von Sir Rufo (Beitrag 1297991)
@milos

Wenn es Unstimmigkeiten / unterschiedliche Lesarten der RFC4180 gibt, wie willst du dann einen Code schreiben, der exakt nach RFC4180 agiert?

Es geht hier nicht um irgendeinen Code sondern um das was die RFC4180 aussagt und ob die Daten nun RFC4180 konform sind oder nicht.

Wenn ich mit jemandem ausmache, dass er mir die Daten nach RFC4180 liefern soll, dann haue ich dem das so lange um die Ohren, bis es so ankommt wie RFC4180 das vorschreibt. Dazu müssen aber alle Beteiligten die RFC4180 gleich verstehen/lesen

Hab ich wohl überlesen, der Code von mir liest die Daten einfach so aus wie sie da sind, ohne ein RF-Ding zu beachten. Hab da wohl einfach drauf los ge-:coder:

Freundliche Grüsse

p80286 16. Apr 2015 14:08

AW: CSV / ASCII-Delimited
 
@Bernhard
Rat mal wie lange ich gebraucht habe um den Ersteller der Datei zu überreden einen nicht proportionalen Font zu nutzen damit er die Leerzeichen wenigsten etwas besser erkennt.
(Nein sie sind falsch!)

@Sir Rufo

Interpretationsfähig ist eben das
Zitat:

enclosed in double-quotes
.
Ich verstehe das als "wenn Anführungszeichen genutzt werden, dann befindet sich der vollständige Feldinhalt innerhalb der Anführungszeichen"
Code:
field = (escaped / non-escaped)

   escaped = DQUOTE *(TEXTDATA / COMMA / CR / LF / 2DQUOTE) DQUOTE

   non-escaped = *TEXTDATA
und dann sollte ich (Leer-)Zeichen zwischen Anführungszeichen und Feldtrenner ignorieren.

Gruß
K-H

Sir Rufo 16. Apr 2015 14:10

AW: CSV / ASCII-Delimited
 
Zitat:

Zitat von milos (Beitrag 1297995)
Zitat:

Zitat von Sir Rufo (Beitrag 1297991)
@milos

Wenn es Unstimmigkeiten / unterschiedliche Lesarten der RFC4180 gibt, wie willst du dann einen Code schreiben, der exakt nach RFC4180 agiert?

Es geht hier nicht um irgendeinen Code sondern um das was die RFC4180 aussagt und ob die Daten nun RFC4180 konform sind oder nicht.

Wenn ich mit jemandem ausmache, dass er mir die Daten nach RFC4180 liefern soll, dann haue ich dem das so lange um die Ohren, bis es so ankommt wie RFC4180 das vorschreibt. Dazu müssen aber alle Beteiligten die RFC4180 gleich verstehen/lesen

Hab ich wohl überlesen, der Code von mir liest die Daten einfach so aus wie sie da sind, ohne ein RF-Ding zu beachten. Hab da wohl einfach drauf los ge-:coder:

Freundliche Grüsse

Jupp, denn dein Code ist nicht RFC4180 konform.

Versuch einfach mal diese Daten zu verarbeiten:
Code:
1,"Das ist
eine Zeile"

taveuni 16. Apr 2015 14:11

AW: CSV / ASCII-Delimited
 
Trotzdem: Wo liegt das eigentliche Problem? Diese Datei ist mit einer TStringlist ja einfach zu parsen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:23 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz