AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Delphi-PRAXiS - Lounge Klatsch und Tratsch Regulärer Ausdruck Zeilenumbruch in Zeile bei CSV ersetzen

Regulärer Ausdruck Zeilenumbruch in Zeile bei CSV ersetzen

Ein Thema von Monday · begonnen am 5. Mai 2021 · letzter Beitrag vom 5. Mai 2021
Antwort Antwort
Seite 1 von 2  1 2   
Monday

Registriert seit: 24. Aug 2012
82 Beiträge
 
FreePascal / Lazarus
 
#1

Regulärer Ausdruck Zeilenumbruch in Zeile bei CSV ersetzen

  Alt 5. Mai 2021, 10:25
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

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:

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)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.280 Beiträge
 
Delphi 10.4 Sydney
 
#2

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

  Alt 5. Mai 2021, 10:41
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

und Zelle = Wert/Value
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014

Geändert von himitsu ( 5. Mai 2021 um 10:46 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
8.383 Beiträge
 
Delphi 10.4 Sydney
 
#3

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

  Alt 5. Mai 2021, 10:48
Nur so aus Interesse: Warum willst du die denn ersetzen? Immerhin verfälscht du damit ja den Inhalt.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.280 Beiträge
 
Delphi 10.4 Sydney
 
#4

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

  Alt 5. Mai 2021, 10:55
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)

Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Benutzerbild von Moombas
Moombas

Registriert seit: 22. Mär 2017
Ort: bei Flensburg
516 Beiträge
 
FreePascal / Lazarus
 
#5

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

  Alt 5. Mai 2021, 11:47
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.
Der Weg ist das Ziel aber man sollte auf dem Weg niemals das Ziel aus den Augen verlieren.
  Mit Zitat antworten Zitat
Monday

Registriert seit: 24. Aug 2012
82 Beiträge
 
FreePascal / Lazarus
 
#6

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

  Alt 5. Mai 2021, 11:48
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 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.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
8.383 Beiträge
 
Delphi 10.4 Sydney
 
#7

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

  Alt 5. Mai 2021, 11:56
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 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.

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)
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.280 Beiträge
 
Delphi 10.4 Sydney
 
#8

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

  Alt 5. Mai 2021, 12:01
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 CountChar('"', S) ginge auch Length(S) - Length(ReplaceStr(S, '"', ''))

statt TStringList geht es auch mit TArray<string> und TFile.ReadAllLines (Delphi 10.x)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014

Geändert von himitsu ( 5. Mai 2021 um 12:33 Uhr) Grund: to -> downto
  Mit Zitat antworten Zitat
Benutzerbild von Moombas
Moombas

Registriert seit: 22. Mär 2017
Ort: bei Flensburg
516 Beiträge
 
FreePascal / Lazarus
 
#9

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

  Alt 5. Mai 2021, 12:26
@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;
Der Weg ist das Ziel aber man sollte auf dem Weg niemals das Ziel aus den Augen verlieren.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.280 Beiträge
 
Delphi 10.4 Sydney
 
#10

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

  Alt 5. Mai 2021, 12:30
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)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014

Geändert von himitsu ( 5. Mai 2021 um 12:32 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +2. Es ist jetzt 02:35 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf