导入CSV报价错误让我疯狂

Ada*_*amA 21 ruby csv

我一直在尝试在ruby-1.9.2中导入CSV文件时遇到令人难以置信的时间.

我试图解析的文件有:

  • 列中的逗号
  • 列内的引号
  • 使用'@'作为:col_sep

csv.txt(代表性输入,真实的是101k行):

?@?@jié@"seal" radical in Chinese characters, (Kangxi radical 26)
Run Code Online (Sandbox Code Playgroud)

我的代码:

require 'csv'

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

我想要的输出:

["?", "?", "jié", "\"seal\" radical in Chinese characters, (Kangxi radical 26)"]
Run Code Online (Sandbox Code Playgroud)

我得到的输出:

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>'
Run Code Online (Sandbox Code Playgroud)

它说有未公开的引用现场,但我可以看到报价开启和关闭.

逃避报价什么也没做.我得到了同样的错误(...@""seal"" r...).将它们更改为单引号使其工作(...@'seal' r...).问题是我需要他们用双引号.

有任何想法吗?

mu *_*ort 57

我认为问题在于CSV试图将其解释"seal"为单引号列; 但是,它似乎并不像@"seal"@解析器那样混淆,因为引号应该包围列.我没有看到任何选项告诉CSV列没有引用但你可以通过设置:quote_char永远不会发生的事情来绕过它.如果您使用的是UTF-8,那么您可以安全地使用零字节作为"永不发生的引用字符":

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

只要没有引用任何列,这应该可以正常工作.

  • +1 CSV规范.与HTML类似,完全被滥用和忽略.对于这两者,有时我会在将数据交给解析器之前修复数据.我认为这也是解决这个问题的方法,但我喜欢你用`quote_char =>"\ x00"来欺骗解析器.不错的工作. (2认同)
  • 我有来自`bcp` MSSQL转储的UTF-16,它实际上有nul字符.为了好玩,我选择了雪人角色(☃)作为替代品.:) (2认同)