4

我有一个简单的 CSV 文件,它使用 | (管道)作为引号字符。将我的 Rails 应用程序从 Ruby 1.9.2 升级到 1.9.3 后,我收到“CSV::MalformedCSVError: Missing or stray quote in line 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       |
4

1 回答 1

6

我认为您刚刚在 CSV ruby​​ 模块中发现了一个错误。从 csv.rb :

1587:  @re_chars =   /#{%"[-][\\.^$?*+{}()|# \r\n\t\f\v]".encode(@encoding)}/

此 Regexp 用于转义与特殊正则表达式符号冲突的字符,包括您的 "pipe" char |。我看不出有任何前置的原因[-],所以如果你删除它,你的例子就会开始工作:

编辑:连字符必须在字符集表达式(用括号括起来[])内转义,仅当不作为前导字符时。所以不得不更新固定的正则表达式:

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       "]]

由于大多数语言不支持带量词的lookbehind 表达式,包括Ruby,我不得不将它写为左括号的否定版本。它还将匹配缺少括号对中左一个的连字符。如果您找到更好的解决方案,请发表评论。

很高兴在向 ruby​​-lang.org 填写错误报告之前听到任何评论。

于 2013-05-14T11:36:43.907 回答