Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Klatsch und Tratsch (https://www.delphipraxis.net/34-klatsch-und-tratsch/)
-   -   Regulärer Ausdruck Zeilenumbruch in Zeile bei CSV ersetzen (https://www.delphipraxis.net/207803-regulaerer-ausdruck-zeilenumbruch-zeile-bei-csv-ersetzen.html)

Monday 5. Mai 2021 09:25

Regulärer Ausdruck Zeilenumbruch in Zeile bei CSV ersetzen
 
Hallo,

ich habe eine CSV Datei. Innerhalb der Zellen (also von " ) sind Zeilenumbrüche. Die möchte ich heraus haben.
Zuerst dachte ich ja, ich bekomme es schnell mit

Delphi-Quellcode:
datei.Text := ReplaceRegExpr('\r\n',datei.Text,' ',True);
heraus. Aber da macht er ja alle Zeilenumbrüche heraus und damit die CSV kaputt.

So klappt es aber auch nicht:

Delphi-Quellcode:
datei.Text := ReplaceRegExpr('(".*?)\r\n(.*?")',datei.Text,'$1 $2',True);
Wobei ich mir auch nicht sicher bin, ob Absatz und Zeilenumbruch das gleiche ist.

Ist mein Vorhaben mit regulären Ausdruck so prinzipiell machbar?!

Liebe Grüße
Monday


Edit: Im Betreff ist mir ein Tippfehler unterlaufen. Korrekt muss es heißen: "Regulärer Ausdruck Zeilenumbruch in ZELLE bei CSV ersetzen" (nicht Zeile)

himitsu 5. Mai 2021 09:41

AW: Regulärer Ausdruck Zeilenumbruch in Zeile bei CSV ersetzen
 
Machbar wäre es mit RegEx schon, aber du musst aufpassen, dass es nicht irgendwo verruscht,
weil z.B. RegEx ein anderes Zeichen ignoriert, oder weil ein " in der Zeile fehlt. (wobei Letzteres "eigentlich" nicht vorkommen dürfte, da sonst die Daten quasi futsch wären, wenn man den "selben" Zeilenumbruch für beide Stellen hätte)


Zitat:

Wobei ich mir auch nicht sicher bin, ob Absatz und Zeilenumbruch das gleiche ist
Hier im Forum suchenHxD Bei Google suchenHxD

Oftmals kenn ich es, dass Zeilenumbruch im "Wert" und der Zeilenumbruch am Datensatzende, unterschiedlich sind (z.B. #10 und #13#10 oder #10 und #13)


[add]
Tippfehler: wechsel in den "erweiterten" Editor :zwinker:

und Zelle = Wert/Value

Uwe Raabe 5. Mai 2021 09:48

AW: Regulärer Ausdruck Zeilenumbruch in Zeile bei CSV ersetzen
 
Nur so aus Interesse: Warum willst du die denn ersetzen? Immerhin verfälscht du damit ja den Inhalt.

himitsu 5. Mai 2021 09:55

AW: Regulärer Ausdruck Zeilenumbruch in Zeile bei CSV ersetzen
 
Ich denke mal seine CSV-Komponente kann mit Zeilenumbrüchen in Values nicht umgehen und trennt stattdessen dort das als Datensatz auf. (was leider auf die meisten Komponenten/Funktion zutrifft)
Auch behandeln viele Komponenten "alle" Arten von Zeilenumbruch gleich. (als Datensatzende)

:stupid:

Moombas 5. Mai 2021 10:47

AW: Regulärer Ausdruck Zeilenumbruch in Zeile bei CSV ersetzen
 
Ganz plump:
- Datei einlesen
- Zeile für Zeile durchgehen (von hinten nach vorne)
- Die " in der Zeile zählen
- Wenn die Anzahl an " ungerade ist, die letzte Zeile hinten an die aktuelle anfügen und löschen
- Datei neu speichern.

Monday 5. Mai 2021 10:48

AW: Regulärer Ausdruck Zeilenumbruch in Zeile bei CSV ersetzen
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1488613)
Nur so aus Interesse: Warum willst du die denn ersetzen? Immerhin verfälscht du damit ja den Inhalt.

Weil wenn ich die CSV in einer Excel Tabelle öffne, dann macht der mir die Zeilenhöhe größer und die Tabelle ist dann unschön und schwer lesbar. Und ich bin zu Faul die Zeilenhöhe zu verändern :-D Wenn du aber weißt, wie man die Zeilenhöhe automatisch auf eine bestimmte standardgröße festlegen kann unabhängig von Zeilenumbrüchen in Zellen, wäre ich auch interessiert. Ich habe jedenfalls keine Einstellung gefunden. Ich nutze für CSV aber gerne OpenOffice, aber da habe ich auch keine Einstellung gefunden. Besonders nice wäre, wenn so eine Einstellung über die CSV ginge, aber das ist völlig unmöglich ;-)

Deshalb dachte ich, ein Einzeller mit Regexpr könnte das Problem auf die schnelle lösen ;-) Der Zellinhalt ist dann zwar etwas zerpflückt, aber damit kann ich leben.

Uwe Raabe 5. Mai 2021 10:56

AW: Regulärer Ausdruck Zeilenumbruch in Zeile bei CSV ersetzen
 
Zitat:

Zitat von himitsu (Beitrag 1488615)
Ich denke mal seine CSV-Komponente kann mit Zeilenumbrüchen in Values nicht umgehen und trennt stattdessen dort das als Datensatz auf.

Mit folgendem Helper für
Delphi-Quellcode:
TTextReader
kann man das aber hinkriegen:
Delphi-Quellcode:
type
  TTextReaderHelper = class helper for TTextReader
    function CharCount(const ALine: string; AChar: Char): Integer;
    procedure ReadQuotedLine(Target: TStrings);
  end;

function TTextReaderHelper.CharCount(const ALine: string; AChar: Char): Integer;
var
  C: Char;
begin
  result := 0;
  for C in ALine do begin
    if C = AChar then
      Inc(result);
  end;
end;

procedure TTextReaderHelper.ReadQuotedLine(Target: TStrings);
var
  line: string;
  line2: string;
  saveStrictDelimiter: Boolean;
begin
  line := ReadLine;
  if Odd(CharCount(line, Target.QuoteChar)) then begin
    { Eine ungerade Anzahl von Quotes bedeutet, daß der gequotete String mindestens einen Zeilenumbruch enthält.
      Wir hängen also die nachfolgenden Zeilen mit LineBreak an, bis eine weitere Zeile mit ungerader Anzahl
      Quotes kommt.
    }
    repeat
      line := line + sLineBreak;
      line2 := ReadLine;
      line := line + line2;
    until Odd(CharCount(line2, Target.QuoteChar));
  end;
  { Zeilenumrüche in line dürfen nicht in separate Einträge zerlegt werden! }
  saveStrictDelimiter := Target.StrictDelimiter;
  try
    Target.StrictDelimiter := True;
    Target.CommaText := line;
  finally
    Target.StrictDelimiter := saveStrictDelimiter;
  end;
end;
Nach dem ReadQuotedLine enthält Target die Liste der Feldwerte, wobei Zeilenumbrüche in einem Wert erhalten bleiben.

Zitat:

Zitat von Monday (Beitrag 1488620)
Weil wenn ich die CSV in einer Excel Tabelle öffne, dann macht der mir die Zeilenhöhe größer und die Tabelle ist dann unschön und schwer lesbar.

Tja, dann hilft dir mein Code leider auch nicht weiter. Oder doch, wenn du ihn dazu benutzt die Zeilenumbrüche zu entfernen. (RegEx wäre mir persönlich da jetzt zu kompliziert)

himitsu 5. Mai 2021 11:01

AW: Regulärer Ausdruck Zeilenumbruch in Zeile bei CSV ersetzen
 
Wie gesagt, mit RegEx sollte es auch gehn. (aber das Ergebnis solltest du noch prüfen, dass auch jeweils die richtigen beiden " zusammen verwendet wurden).

Das von Moombas, wäre in etwa so

Delphi-Quellcode:
SL := TStringList.Create;
SL.LoadFromFile(...);
for i := SL.Count - 2 downto 0 do
  // if Odd(SL[i + 1].CountChar('"')) then begin // Delphi 10.x
  if Odd(CountChar('"', SL[i + 1])) then begin // irgendwo eine Funktion suchen, die sowas macht
    SL[i] := SL[i] + 'dasTennzeichen' + SL[i + 1];
    SL.Delete(i + 1);
  end;
SL.SaveToFile(...);
SL.Free;
von vorne nach hinten geht auch, aber hab keine Lust auf While mit Inc(i)

statt
Delphi-Quellcode:
CountChar('"', S)
ginge auch
Delphi-Quellcode:
Length(S) - Length(ReplaceStr(S, '"', ''))


statt TStringList geht es auch mit TArray<string> und TFile.ReadAllLines (Delphi 10.x)

Moombas 5. Mai 2021 11:26

AW: Regulärer Ausdruck Zeilenumbruch in Zeile bei CSV ersetzen
 
@himitsu: Hab wohl grad nen Knoten im Hirn: Musst du nicht, wenn man Zeilen löscht von hinten anfangen um nicht am Ende "über das Ziel hinaus zu schießen?
Ich wäre daher eher bei:
Delphi-Quellcode:
SL := TStringList.Create;
SL.LoadFromFile(...);
for i := SL.Count - 2 downto 0 do
  // if Odd(SL[i + 1].CountChar('"')) then begin // Delphi 10.x
  if Odd(CountChar('"', SL[i + 1])) then begin // irgendwo eine Funktion suchen, die sowas macht
    SL[i] := SL[i] + 'dasTennzeichen' + SL[i + 1];
    SL.Delete(i + 1);
  end;
SL.SaveToFile(...);
SL.Free;

himitsu 5. Mai 2021 11:30

AW: Regulärer Ausdruck Zeilenumbruch in Zeile bei CSV ersetzen
 
ja stimmt (war ein schreibfehler downto statt to)

und wenn von vorne, mit WHILE, weil FOR das Ende cached (zu Beginn in eine Variable speichert und Count somit nicht anpasst)


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:08 Uhr.
Seite 1 von 2  1 2   

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