【问题标题】:quote_char causing fits in ruby CSV importquote_char 导致适合 ruby​​ CSV 导入
【发布时间】:2013-05-06 20:36:44
【问题描述】:

我有一个简单的 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       |

【问题讨论】:

  • 如何从 public/sample_file.csv 添加几行来向我们展示数据?
  • @hd1 完成 - 请参见上文!
  • 我也不例外。文件中是否有任何有趣的字节?如果你cat -v CSV,有什么奇怪的地方吗?
  • @muistooshort 没有奇怪的字符。这是 link to the sample file 如果你愿意,here's a screenshot 是 cat -v 的输出
  • CSV.foreach 也有问题。如果您删除 quote_char 选项,一切正常。

标签: ruby csv ruby-1.9.3 ruby-1.9.2 ruby-2.0


【解决方案1】:

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

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

此正则表达式用于转义与特殊正则表达式符号冲突的字符,包括您的“管道”字符 | 。 我看不出前面有任何原因 [-],所以如果你删除它,你的例子就开始起作用了:

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

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 填写错误报告之前听到任何 cmets。

【讨论】:

  • Ruby 2.0.0p195 刚刚发布,它并没有解决这个问题,因此如果您愿意,请提交错误并提交补丁。
  • 已经有人填写了错误报告 - bugs.ruby-lang.org/issues/8405
猜你喜欢
  • 2012-08-23
  • 1970-01-01
  • 2014-06-16
  • 2012-02-14
  • 2016-03-24
  • 2015-12-31
  • 2021-11-17
  • 2018-08-12
  • 2015-03-01
相关资源
最近更新 更多