true - ruby csv to hash



L'importation d'une erreur de devis CSV me rend fou (1)

J'ai eu un temps incroyable en essayant d'importer un fichier CSV dans ruby-1.9.2.

Le fichier que j'essaie d'analyser a:

  • virgules dans les colonnes
  • citations dans les colonnes
  • utilise un '@' comme: col_sep

csv.txt (entrée représentative, la vraie est 101k lignes):

㔾@㔾@jié@"seal" radical in Chinese characters, (Kangxi radical 26)

Mon code:

require 'csv'

CSV.foreach("/Users/adam/Desktop/csvtest.txt", {:col_sep => "@"}) do |row|
    puts row.to_s 
end

Ma sortie souhaitée:

["㔾", "㔾", "jié", "\"seal\" radical in Chinese characters, (Kangxi radical 26)"]

Ce que je reçois pour la sortie:

CSV::MalformedCSVError: Unclosed quoted field on line 1.
from /Users/adam/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/CSV.rb:1910:in `block in shift'
from /Users/adam/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/CSV.rb:1825:in `loop'
from /Users/adam/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/CSV.rb:1825:in `shift'
from /Users/adam/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/CSV.rb:1767:in `each'
from /Users/adam/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/CSV.rb:1202:in `block in foreach'
from /Users/adam/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/CSV.rb:1340:in `open'
from /Users/adam/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/CSV.rb:1201:in `foreach'
from (irb):31
from /Users/adam/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'

Il dit qu'il y a des fichiers cités non fermés, mais je peux voir que les guillemets s'ouvrent et se ferment.

Echapper aux citations ne fait rien. Je reçois la même erreur ( [email protected]""seal"" r... ). Les transformer en guillemets simples le fait fonctionner ( [email protected]'seal' r... ). Le problème est que je BESOIN qu'ils soient entre guillemets.

Des idées?


Je pense que le problème est que CSV essaie d'interpréter "seal" comme une seule colonne citée; mais, il n'apparaît pas comme @"seal"@ donc l'analyseur est confus car les guillemets sont censés entourer les colonnes. Je ne vois aucune option pour dire à CSV que les colonnes ne sont pas entre guillemets mais vous pouvez les contourner en définissant :quote_char à quelque chose qui ne se produira jamais. Si vous utilisez UTF-8, vous pouvez utiliser un octet zéro en toute sécurité comme "caractère de citation qui ne se produira jamais":

CSV.foreach(filename, :col_sep => "@", :quote_char => "\x00") do |row|
    #...
end

Cela devrait fonctionner tant qu'aucune de vos colonnes n'est citée.





csv