Vin*_*e W 4 ruby csv ruby-1.9.2 ruby-1.9.3 ruby-2.0
我有一个使用|的简单CSV文件 (管道)作为引用字符.将我的rails应用程序从Ruby 1.9.2升级到1.9.3后,我收到"CSV :: MalformedCSVError:第1行中缺少或流浪的引用"错误.
如果我弹出打开vim并替换| 使用常规引号,单引号甚至"=",文件工作正常,但是| 和*导致错误.有人对可能导致这种情况的原因有任何疑问吗?这是一个可以重现错误的简单单线程:
@csv = CSV.read("public/sample_file.csv", {quote_char: '|', headers: false})
Run Code Online (Sandbox Code Playgroud)
同样在Ruby 2.0和irb w/out load rails中重现了这一点.
编辑:以下是CSV中的一些示例行
|076N102 |,|CARD |,| 1|,|NEW|,|PCS |
|07-1801 |,|BASE |,| 18|,|NEW|,|PCS |
Run Code Online (Sandbox Code Playgroud)
我想你刚刚发现了CSV ruby模块中的一个错误.来自csv.rb:
1587: @re_chars = /#{%"[-][\\.^$?*+{}()|# \r\n\t\f\v]".encode(@encoding)}/
Run Code Online (Sandbox Code Playgroud)
此Regexp用于转义与特殊正则表达式符号冲突的字符,包括"管道"字符|.我没有看到任何前置的原因[-],所以如果你删除它,你的例子开始工作:
编辑:[]只有当不作为主角时,连字符必须在字符集表达式内(用括号括起来)进行转义.所以不得不更新固定的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 "]]
Run Code Online (Sandbox Code Playgroud)
由于大多数语言都不支持带有量词的lookbehind表达式,包括Ruby,我不得不把它写成左括号的负面版本.它还会匹配连字符与缺少左侧一个括号对的连字符.如果您找到更好的解决方案,请发表评论.
很高兴听到任何评论,然后填写错误报告给ruby-lang.org.