我有一个简单的 CSV 文件,它使用 | (管道)作为引号字符。将我的 Rails 应用程序从 Ruby 1.9.2 升级到 1.9.3 后,我收到“CSV::MalformedCSVError:第 1 行中缺少或杂散的引号”错误。
如果我打开 vim 并替换 |使用正引号、单引号甚至“=”,文件工作正常,但是 |和 * 导致错误。有人对可能导致这种情况的原因有任何想法吗?这是一个可以重现错误的简单单行代码:
@csv = CSV.read("public/sample_file.csv", {quote_char: '|', headers: false})
也在 Ruby 2.0 和 irb w/out loading rails 中重现了这一点。
编辑:这里是 CSV 中的一些示例行
|076N102 |,|CARD |,| 1|,|NEW|,|PCS |
|07-1801 |,|BASE |,| 18|,|NEW|,|PCS |
最佳答案
我认为您刚刚在 CSV ruby 模块中发现了一个错误。 来自 csv.rb:
1587: @re_chars = /#{%"[-][\\.^$?*+{}()|# \r\n\t\f\v]".encode(@encoding)}/
此 Regexp 用于转义与特殊正则表达式符号冲突的字符,包括您的“管道”字符 |
。
我看不出任何前置 [-]
的原因,所以如果您删除它,您的示例就会开始工作:
编辑:仅当连字符不是前导字符时,才必须在字符集表达式(用方括号 []
括起来)内对连字符进行转义。所以必须更新固定的正则表达式:
1587: @re_chars = /#{%"(?<!\\[)-(?=.*\\])|[\\.^$?*+{}()|# \r\n\t\f\v]".encode(@encoding)}/
CSV.read('sample.csv', {quote_char: '|'})
# [["076N102 ",
# "CARD ",
# " 1", "NEW", "PCS "],
# ["07-1801 ",
# "BASE ",
# " 18", "NEW", "PCS "]]
由于大多数语言不支持带有量词的后向表达式,包括 Ruby,我不得不将其写成左括号的否定版本。它还会匹配括号对中缺少左边一个的连字符。如果您找到更好的解决方案,请发表评论。
很高兴在向 ruby-lang.org 提交错误报告之前听到任何意见。
关于ruby - quote_char 导致适合 ruby CSV 导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16511411/