Ich suche nach Vorschlägen für den Umgang mit einer CSV-Datei, die erstellt und dann von unseren Kunden hochgeladen wird und die möglicherweise ein Komma in einem Wert wie einem Firmennamen enthält.
Einige der Ideen, die wir betrachten, sind: zitierte Bezeichner (Wert "," Werte "," usw.) oder die Verwendung eines | anstelle eines Kommas. Das größte Problem ist, dass wir es einfach machen müssen, sonst wird der Kunde es nicht tun.
Antworten:
Wie andere bereits gesagt haben, müssen Sie Werte mit Anführungszeichen umgehen. Hier ist ein kleiner CSV-Reader in C♯, der Anführungszeichen unterstützt, einschließlich eingebetteter Anführungszeichen und Zeilenumbrüche.
Dies ist übrigens ein Unit-getesteter Code. Ich poste es jetzt, weil diese Frage häufig auftaucht und andere möglicherweise nicht die gesamte Bibliothek wünschen, wenn eine einfache CSV-Unterstützung ausreicht.
Sie können es wie folgt verwenden:
Hier sind die Klassen. Beachten Sie, dass Sie die
Csv.Escape
Funktion auch zum Schreiben einer gültigen CSV verwenden können.quelle
Für 2017 ist csv vollständig spezifiziert - RFC 4180.
Es ist eine sehr verbreitete Spezifikation und wird von vielen Bibliotheken vollständig abgedeckt ( Beispiel ).
Verwenden Sie einfach eine leicht verfügbare CSV-Bibliothek - also RFC 4180.
Es gibt tatsächlich eine Spezifikation für das CSV-Format und den Umgang mit Kommas:
http://tools.ietf.org/html/rfc4180
Um Werte zu haben
foo
undbar,baz
dies zu tun, tun Sie Folgendes:Eine weitere wichtige Anforderung, die berücksichtigt werden muss (auch aus der Spezifikation):
quelle
System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator
.Das CSV-Format verwendet Kommas, um Werte zu trennen. Werte, die Zeilenumbrüche, Zeilenvorschübe, Kommas oder doppelte Anführungszeichen enthalten, sind von doppelten Anführungszeichen umgeben. Werte, die doppelte Anführungszeichen enthalten, werden in Anführungszeichen gesetzt und jedes Literal-Anführungszeichen wird durch ein unmittelbar vorhergehendes Anführungszeichen maskiert: Zum Beispiel die 3 Werte:
würde codiert werden als:
Jedes Feld kann in Anführungszeichen gesetzt werden, aber nur Felder, die Kommas, CR / NL oder Anführungszeichen enthalten, müssen in Anführungszeichen gesetzt werden.
Es gibt keinen wirklichen Standard für das CSV-Format, aber fast alle Anwendungen folgen den hier dokumentierten Konventionen . Der an anderer Stelle erwähnte RFC ist kein Standard für CSV, sondern ein RFC für die Verwendung von CSV in MIME und enthält einige unkonventionelle und unnötige Einschränkungen, die ihn außerhalb von MIME unbrauchbar machen.
Ein Problem, das viele CSV-Module, die ich gesehen habe, nicht berücksichtigen, ist die Tatsache, dass mehrere Zeilen in einem einzigen Feld codiert werden können. Dies bedeutet, dass Sie nicht davon ausgehen können, dass jede Zeile ein separater Datensatz ist. Sie müssen entweder keine Zeilenumbrüche in Ihrem zulassen Daten oder darauf vorbereitet sein.
quelle
Setzen Sie doppelte Anführungszeichen um Zeichenfolgen. Das macht Excel im Allgemeinen .
Ala Eli,
quelle
Sie können die Felder in doppelte Anführungszeichen setzen. Ich mag diesen Ansatz nicht, da er ein weiteres Sonderzeichen hinzufügt (das doppelte Anführungszeichen). Definieren Sie einfach ein Escape-Zeichen (normalerweise Backslash) und verwenden Sie es überall dort, wo Sie etwas entkommen müssen:
Sie müssen nicht versuchen, Anführungszeichen abzugleichen, und Sie müssen weniger Ausnahmen analysieren. Dies vereinfacht auch Ihren Code.
quelle
Über nuget steht eine Bibliothek zur Verfügung, die sich mit so ziemlich jedem wohlgeformten CSV (.net) - CsvHelper befasst
Beispiel für die Zuordnung zu einer Klasse:
Beispiel zum Lesen einzelner Felder:
Lassen Sie den Client das Dateiformat steuern:
,
ist das Standardfeldtrennzeichen,"
der Standardwert, der zum Escapezeichen von Feldern verwendet wird, die ein Trennzeichen, ein Anführungszeichen oder ein Zeilenende enthalten.So verwenden Sie (zum Beispiel)
#
Felder und'
Escapezeichen:Weitere Dokumentation
quelle
CsvHelper
Bibliothek zur Lösung des OP-Problems angeben würden.Wie in meinem Kommentar zu Harpos Antwort erwähnt, ist seine Lösung gut und funktioniert in den meisten Fällen. In einigen Szenarien, in denen Kommas direkt nebeneinander liegen, werden die Kommas jedoch nicht aufgeteilt.
Dies liegt daran, dass sich die Regex-Zeichenfolge unerwartet als Vertabim-Zeichenfolge verhält. Damit sich dieses Verhalten korrekt verhält, müssen alle "Zeichen in der Regex-Zeichenfolge manuell maskiert werden, ohne das Vertabim-Escape zu verwenden.
Dh. Die Regex sollte dies sein, indem manuelle Escapezeichen verwendet werden:
",(?=(?:[^\"\"]*\"\"[^\"\"]*\"\")*(?![^\"\"]*\"\"))"
was übersetzt in
",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))"
Wenn Sie eine Vertabim-Zeichenfolge verwenden
@",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))"
, verhält sie sich wie folgt: Sie können sehen, ob Sie den regulären Ausdruck debuggen:Zusammenfassend kann ich die Lösung von harpo empfehlen, aber achten Sie auf dieses kleine Problem!
Ich habe eine kleine optionale Ausfallsicherheit in den CsvReader aufgenommen, um Sie zu benachrichtigen, wenn dieser Fehler auftritt (wenn Sie eine zuvor bekannte Anzahl von Spalten haben):
Dies kann über den Konstruktor injiziert werden:
quelle
[^""]
dasselbe wie[^"]
? Das Duplizieren eines Zeichens innerhalb einer Zeichenklassenspezifikation ist überflüssig, oder?Fügen Sie einen Verweis auf Microsoft.VisualBasic hinzu (ja, dort steht VisualBasic, aber es funktioniert genauso gut in C # - denken Sie daran, dass am Ende alles nur IL ist).
Verwenden Sie die
Microsoft.VisualBasic.FileIO.TextFieldParser
Klasse, um die CSV-Datei zu analysieren. Hier ist der Beispielcode:quelle
parser.HasFieldsEnclosedInQuotes = true;
und die Eingabedatei müsste Felder, die Kommas in Anführungszeichen enthalten, gemäß der CSV-Spezifikation einschließen - Excel tut dies bereits.Sie können alternative "Trennzeichen" wie ";" verwenden. oder "|" Am einfachsten ist jedoch möglicherweise das Zitieren, das von den meisten (anständigen) CSV-Bibliotheken und den meisten anständigen Tabellen unterstützt wird.
Weitere Informationen zu CSV-Trennzeichen und eine Spezifikation für ein Standardformat zur Beschreibung von Trennzeichen und Zitieren finden Sie auf dieser Webseite
quelle
Wenn Sie sich auf einem * nix-System befinden , Zugriff auf
sed
ein oder mehrere unerwünschte Kommas nur in einem bestimmten Feld Ihrer CSV haben und diese vorhanden sein können , können Sie den folgenden Einzeiler verwenden, um sie"
als RFC4180-Abschnitt einzuschließen 2 schlägt vor:Abhängig davon, in welchem Feld sich die unerwünschten Kommas befinden, müssen Sie die Erfassungsgruppen des regulären Ausdrucks (und der Ersetzung) ändern / erweitern.
Im obigen Beispiel wird das vierte Feld (von sechs) in Anführungszeichen gesetzt.
In Kombination mit der
--in-place
Option -option können Sie diese Änderungen direkt auf die Datei anwenden.Um den richtigen regulären Ausdruck zu "bauen", gibt es ein einfaches Prinzip:
[^,]*,
und fügen sie alle in einer Erfassungsgruppe zusammen.(.*)
.,.*
und fügen sie alle zu einer Erfassungsgruppe zusammen.Hier finden Sie eine kurze Übersicht über verschiedene mögliche Regexe / Substitutionen je nach Fachgebiet. Wenn nicht angegeben, ist die Substitution
\1"\2"\3
.Wenn Sie unerwünschte Kommas entfernen möchten,
sed
anstatt sie in Anführungszeichen zu setzen, lesen Sie diese Antwort .quelle
Wenn Sie das Rad neu erfinden möchten, kann Folgendes für Sie funktionieren:
quelle
In Europa müssen wir dieses Problem früher als diese Frage haben. In Europa verwenden wir alle ein Komma als Dezimalpunkt. Siehe diese Zahlen unten:
Daher ist es nicht möglich, das Komma-Trennzeichen für CSV-Dateien zu verwenden. Aus diesem Grund werden die CSV-Dateien in Europa durch ein Semikolon (
;
) getrennt .Programme wie Microsoft Excel können Dateien mit einem Semikolon lesen und vom Trennzeichen wechseln. Sie können sogar ein tab (
\t
) als Trennzeichen verwenden. Siehe diese Antwort vom Supper User .quelle
Wenn Sie an einer ausführlicheren Übung zum Parsen von Dateien im Allgemeinen interessiert sind (am Beispiel von CSV), können Sie diesen Artikel lesen von Julian Bucknall lesen. Ich mag den Artikel, weil er die Dinge in viel kleinere Probleme aufteilt, die viel weniger unüberwindbar sind. Sie erstellen zuerst eine Grammatik, und sobald Sie eine gute Grammatik haben, ist es ein relativ einfacher und methodischer Prozess, die Grammatik in Code umzuwandeln.
Der Artikel verwendet C # und hat unten einen Link zum Herunterladen des Codes.
quelle
Hier ist eine nette kleine Problemumgehung:
Sie können stattdessen ein griechisches Zeichen für die untere Zahl verwenden (U + 0375).
Es sieht so aus ͵
Mit dieser Methode sparen Sie auch viele Ressourcen ...
quelle
Verwenden Sie einfach SoftCircuits.CsvParser auf NuGet. Es behandelt all diese Details für Sie und verarbeitet sehr große Dateien effizient. Bei Bedarf können sogar Objekte importiert / exportiert werden, indem Spalten Objekteigenschaften zugeordnet werden. Außerdem haben meine Tests gezeigt, dass es im Durchschnitt fast viermal schneller ist als der beliebte CsvHelper.
quelle
Da es sich um allgemeine Praktiken handelt, gehen wir von den Faustregeln aus:
Verwenden Sie keine CSV-Datei, sondern XML mit einer Bibliothek, um stattdessen die XML-Datei zu lesen und zu schreiben.
Wenn Sie CSV verwenden müssen. Machen Sie es richtig und verwenden Sie eine kostenlose Bibliothek, um die CSV-Dateien zu analysieren und zu speichern.
Um 1) zu rechtfertigen, sind die meisten CSV-Parser nicht codierungsbewusst. Wenn Sie also nicht mit US-ASCII arbeiten, fragen Sie nach Problemen. Zum Beispiel speichert Excel 2002 die CSV in lokaler Codierung ohne Hinweis auf die Codierung. Der CSV-Standard ist nicht weit verbreitet :(. Andererseits ist der XML-Standard gut übernommen und handhabt Codierungen ziemlich gut.
Um 2) zu rechtfertigen: Es gibt Unmengen von CSV-Parsern für fast alle Sprachen, sodass das Rad nicht neu erfunden werden muss, selbst wenn die Lösungen recht einfach aussehen.
Um nur einige zu nennen:
Verwenden Sie für Python das eingebaute CSV- Modul
Überprüfen Sie für Perl CPAN und Text :: CSV
Für PHP verwenden Sie eingebaute fgetcsv / fputcsv Funktionen
Für Java überprüfen Sie die SuperCVS- Bibliothek
Es ist wirklich nicht erforderlich, dies von Hand zu implementieren, wenn Sie es nicht auf einem eingebetteten Gerät analysieren möchten.
quelle
Sie können die CSV-Datei so lesen.
Dies nutzt Splits und kümmert sich um Räume.
quelle
Fragen wir uns zunächst: "Warum müssen wir Kommas für CSV-Dateien anders behandeln?"
Für mich lautet die Antwort: "Wenn ich Daten in eine CSV-Datei exportiere, verschwinden die Kommas in einem Feld und mein Feld wird in mehrere Felder aufgeteilt, in denen die Kommas in den Originaldaten erscheinen." (Das liegt daran, dass das Komma das CSV-Feldtrennzeichen ist.)
Abhängig von Ihrer Situation können Semikolons auch als CSV-Feldtrennzeichen verwendet werden.
Aufgrund meiner Anforderungen kann ich ein Zeichen verwenden, z. B. ein einzelnes Anführungszeichen mit niedriger 9, das wie ein Komma aussieht.
So können Sie es in Go machen:
Das zweite Komma in der Ersetzungsfunktion ist die Dezimalzahl 8218.
Beachten Sie, dass dieses Dezima 8218-Zeichen nicht wie ein Komma aussieht, wenn Sie Clients haben, die möglicherweise nur ASCII-Textleser haben. Wenn dies der Fall ist, würde ich empfehlen, das Feld mit einem Komma (oder Semikolon) in doppelten Anführungszeichen gemäß RFC 4128 zu umgeben: https://tools.ietf.org/html/rfc4180
quelle
Im Allgemeinen codiere ich die Felder, die Kommas oder Sonderzeichen enthalten können, per URL. Und dekodieren Sie es dann, wenn es in einem beliebigen visuellen Medium verwendet / angezeigt wird.
(Kommas werden zu% 2C)
Jede Sprache sollte Methoden zum URL-Codieren und Decodieren von Zeichenfolgen haben.
zB in Java
Ich weiß, dass dies eine sehr allgemeine Lösung ist und möglicherweise nicht ideal für Situationen ist, in denen Benutzer den Inhalt von CSV-Dateien manuell anzeigen möchten.
quelle
Normalerweise mache ich das in meinen CSV-Dateien, die Routinen analysieren. Angenommen, die Variable 'line' ist eine Zeile in einer CSV-Datei und alle Werte der Spalten sind in doppelte Anführungszeichen eingeschlossen. Nachdem die folgenden zwei Zeilen ausgeführt wurden, erhalten Sie CSV-Spalten in der Auflistung 'values'.
quelle
Die einfachste Lösung, die ich gefunden habe, ist die, die LibreOffice verwendet:
"
durch”
Sie können auch die von Excel verwendete verwenden:
"
durch""
Beachten Sie, dass andere Personen empfohlen haben, nur Schritt 2 oben auszuführen. Dies funktioniert jedoch nicht mit Zeilen, in denen a
"
von a gefolgt wird,
, wie in einer CSV, in der Sie eine einzelne Spalte mit der Zeichenfolge haben möchtenhello",world
, wie die CSV lauten würde:Welches als eine Zeile mit zwei Spalten interpretiert wird:
hello
undworld"
quelle
hello",world
Feld müsste einfach als gespeichert werden"hello"",world"
, was zu 100% korrekt analysiert werden kann.quelle
Ich habe die Csvreader-Bibliothek verwendet, aber dadurch habe ich Daten erhalten, indem ich durch Komma (,) im Spaltenwert explodiert bin.
Wenn Sie also CSV-Dateidaten einfügen möchten, die in den meisten Spaltenwerten Komma (,) enthalten, können Sie die folgende Funktion verwenden. Autorenlink => https://gist.github.com/jaywilliams/385876
quelle
Ich habe die papaParse-Bibliothek verwendet, um die CSV-Datei zu analysieren und die Schlüssel-Wert-Paare (Schlüssel / Header / erste Zeile des CSV-Datei-Werts) zu haben.
Hier ist ein Beispiel, das ich benutze:
https://codesandbox.io/embed/llqmrp96pm
Es enthält die Datei dummy.csv, um die CSV-Parsing-Demo zu erhalten.
Ich habe es in reactJS verwendet, obwohl es einfach und unkompliziert in einer App zu replizieren ist, die mit einer beliebigen Sprache geschrieben wurde.
quelle
Ein Beispiel könnte zeigen, wie Kommas in einer CSV-Datei angezeigt werden können. Erstellen Sie eine einfache Textdatei wie folgt:
Speichern Sie diese Textdatei als Textdatei mit dem Suffix ".csv" und öffnen Sie sie mit Excel 2000 unter Windows 10.
aa, bb, cc, d; d "In der Tabellenkalkulation sollte die folgende Zeile wie die obige Zeile aussehen, außer dass die folgende Zeile ein angezeigtes Komma anstelle eines Semikolons zwischen den ds zeigt." aa, bb, cc, "d, d", Dies funktioniert sogar in Excel
aa, bb, cc, "d, d", Dies funktioniert sogar in Excel 2000 aa, bb, cc, "d, d", Dies funktioniert sogar in Excel 2000 aa, bb, cc, "d, d", Dies funktioniert sogar in Excel 2000
aa, bb, cc, "d, d", Dies schlägt in Excel 2000 aufgrund des Leerzeichens vor dem ersten Anführungszeichen fehl. aa, bb, cc, "d, d". Dies schlägt in Excel 2000 aufgrund des Leerzeichens vor dem ersten Anführungszeichen fehl aa, bb, cc, "d, d". Dies schlägt in Excel 2000 aufgrund des Leerzeichens vor dem ersten Anführungszeichen fehl
aa, bb, cc, "d, d", Dies funktioniert auch in Excel 2000 auch mit Leerzeichen vor und nach dem 2. Anführungszeichen. aa, bb, cc, "d, d", Dies funktioniert auch in Excel 2000 auch mit Leerzeichen vor und nach dem 2. Anführungszeichen. aa, bb, cc, "d, d", Dies funktioniert auch in Excel 2000 auch mit Leerzeichen vor und nach dem 2. Anführungszeichen.
Regel: Wenn Sie ein Komma in einer Zelle (Feld) einer CSV-Datei anzeigen möchten: "Beginnen und beenden Sie das Feld mit doppelten Anführungszeichen, aber vermeiden Sie Leerzeichen vor dem ersten Anführungszeichen."
quelle
Ich denke, die einfachste Lösung für dieses Problem besteht darin, dass der Kunde die CSV in Excel öffnet und dann Strg + R, um alle Kommas durch die gewünschte Kennung zu ersetzen. Dies ist für den Kunden sehr einfach und erfordert nur eine Änderung Ihres Codes, um das Trennzeichen Ihrer Wahl zu lesen.
quelle
Verwenden Sie ein Tabulatorzeichen (\ t), um die Felder zu trennen.
quelle