quote_char导致适合ruby CSV导入

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)

Tor*_*mus 6

我想你刚刚发现了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.