Ich habe eine CSV-Datei mit ziemlich unregelmäßigen Einträgen. Der erste Eintrag einer Zeile hat keine umschließenden Anführungszeichen, wird die ganze Zeile zitiert, und jedes Feld doppelt so hoch ist wie folgt zitiert:Ruby: CSV mit irregulären Feldern bereinigen
# my_file.csv, opened with sublime text :
# Headers
"first_name,""last_name"",""username"",""phone_number"",""address"",""email_address"",""email_address_confirmed"",""joined_at"",""status"",""is_admin"",""accept_emails_from_admin"",""language"",""can_post_listings"""
# Sample entry
"Mr X,""Mr X"",""mrxxx"","""","""",""[email protected]"",""true"",""2015-09-21 09:08:51 UTC"",""accepted"",""true"",""true"",""fr"",""true"""
ich konnte Vorprozess die Datei etwas anderes als Rubin (Excel, ein einfach regex/ersetzen, oder alles, was Sie denken könnten), aber da ich wahrscheinlich mehrere Male tun muss, wäre eine Ruby-Lösung großartig.
Derzeit bin ich mit
csv = File.open(csv_file_path)
CSV.parse(csv, :headers => true)
nur Und ich sehe nicht wirklich, wie ich diese Differenz leicht jede Reihe nur für den ersten Eintrag beheben könnte ...
Das Problem ist die CSV wird nicht korrekt analysiert und betrachtet stattdessen jede Zeile als eine einzelne Zeichenfolge (anstelle eines Arrays mit so vielen Elementen wie Spalten).
# csv.headers : note this is an array with a single string
["first_name,\"last_name\",\"username\",\"phone_number\",\"address\",\"email_address\",\"email_address_confirmed\",\"joined_at\",\"status\",\"is_admin\",\"accept_emails_from_admin\",\"language\",\"can_post_listings\""]
# csv.to_a.last
["xxx,\"xxxx\",\"martin\",\"\",\"\",\"[email protected]\",\"false\",\"2016-05-12 13:06:53 UTC\",\"pending_email_confirmation\",\"false\",\"true\",\"fr\",\"false\""]
EDIT: ich versucht haben folgendes
processed = File.readlines(path).map do |row|
row.strip # strip newlines
.gsub(/^\"|\"$/, '') # remove outer quotes
.gsub(/\"\"/, '"') # fix double quotes
end
CSV.parse(processed.join('\n'))
I laufen in eine CSV::MalformedCSVError: Missing or stray quote in line 1
Musterausgänge
# File.readlines(path).first
# => "\"first_name,\"\"last_name\"\",\"\"username\"\",\"\"phone_number\"\",\"\"address\"\",\"\"email_address\"\",\"\"email_address_confirmed\"\",\"\"joined_at\"\",\"\"status\"\",\"\"is_admin\"\",\"\"accept_emails_from_admin\"\",\"\"language\"\",\"\"can_post_listings\"\"\"\n"
# processed.first
# => "first_name,\"last_name\",\"username\",\"phone_number\",\"address\",\"email_address\",\"email_address_confirmed\",\"joined_at\",\"status\",\"is_admin\",\"accept_emails_from_admin\",\"language\",\"can_post_listings\""
EDIT 2
Ouch, habe ich einige nein manchmal Komm-Kommas, und Daves Antwort scheint in diesen Fällen zu versagen. Es ist dieses Feld
"" 45, street_addr - Place ""
, die ein Komma enthält, die kein Trennzeichen ist. Der vollständige Eintrag
"Mr x,""Mr xx"",""bbernelin"","""",""45, street_addr - Place"",""[email protected]"",""true"",""2016-04-13 11:14:08 UTC"",""accepted"",""false"",""true"",""fr"",""true"""
gibt es mehr Zitat s in Ihrem Beispiel, das Sie in Ihrer Beschreibung angeben. Es gibt ein Zitat am Anfang jeder Zeile und zwei Anführungszeichen auf jeder Seite jedes Feldes nach dem ersten. Ich denke, die Antwort, die ich gepostet habe, wird für dich funktionieren, aber wenn du dein Beispiel mit deiner Beschreibung übereinstimmst, könnten wir vielleicht die Lösung vereinfachen. –