![]() |
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:
heraus. Aber da macht er ja alle Zeilenumbrüche heraus und damit die CSV kaputt.
datei.Text := ReplaceRegExpr('\r\n',datei.Text,' ',True);
So klappt es aber auch nicht:
Delphi-Quellcode:
Wobei ich mir auch nicht sicher bin, ob Absatz und Zeilenumbruch das gleiche ist.
datei.Text := ReplaceRegExpr('(".*?)\r\n(.*?")',datei.Text,'$1 $2',True);
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) |
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:
![]() ![]() 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 |
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.
|
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: |
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. |
AW: Regulärer Ausdruck Zeilenumbruch in Zeile bei CSV ersetzen
Zitat:
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. |
AW: Regulärer Ausdruck Zeilenumbruch in Zeile bei CSV ersetzen
Zitat:
Delphi-Quellcode:
kann man das aber hinkriegen:
TTextReader
Delphi-Quellcode:
Nach dem ReadQuotedLine enthält Target die Liste der Feldwerte, wobei Zeilenumbrüche in einem Wert erhalten bleiben.
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; Zitat:
|
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:
von vorne nach hinten geht auch, aber hab keine Lust auf While mit Inc(i)
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; statt
Delphi-Quellcode:
ginge auch
CountChar('"', S)
Delphi-Quellcode:
Length(S) - Length(ReplaceStr(S, '"', ''))
statt TStringList geht es auch mit TArray<string> und TFile.ReadAllLines (Delphi 10.x) |
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; |
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 14:37 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