【问题标题】:fix invalid CSV row with "Illegal quoting" error in Ruby code修复 Ruby 代码中带有“非法引用”错误的无效 CSV 行
【发布时间】:2012-05-22 14:30:00
【问题描述】:

由于某种原因,csv 文件中有一些行带有“非法引用”错误,例如:

1336481227,178.108.171.183,3.2.0,9700132ccc02e12a,c083b5d2-ec92-486f-a5b3-512dba1ce4ae,invoke_action,"{""timestamp"":""2012-05-08 13:47:26""} "

1336481227,178.108.171.183,3.2.0,9700132ccc02e12a,c083b5d2-ec92-486f-a5b3-512dba1ce4ae,invoke_action,{""timestamp"":""2012-05-08 13:47:27""}

第一行是正确的。但是第二行的最后一个字段 {""timestamp"":""2012-05-08 13:47:27""} 缺少大括号外的双引号,所以当我尝试时

CSV.foreach(csv_file_path) do |row|
    puts "======================="
    puts row
    puts "======================="
end

我有错误

=======================
1336481227
178.108.171.183
3.2.0
9700132ccc02e12a
c083b5d2-ec92-486f-a5b3-512dba1ce4ae
invoke_action
{"timestamp":"2012-05-08 13:47:26","a":"b"}
=======================
#<CSV::MalformedCSVError: Illegal quoting in line 2.>

有没有办法解决这个问题,或者在发生错误时跳过它?

编辑: 如果我尝试

CSV.foreach(csv_file_path, :quote_char => "\'") do |row|
    puts "======================="
    puts row
    puts "======================="
end

第一行的 JSON 格式值被破坏了:

=======================
1336481227
178.108.171.183
3.2.0
9700132ccc02e12a
c083b5d2-ec92-486f-a5b3-512dba1ce4ae
invoke_action
"{""timestamp"":""2012-05-08 13:47:26""
""a"":""b""}"
=======================
=======================
1336481227
178.108.171.183
3.2.0
9700132ccc02e12a
c083b5d2-ec92-486f-a5b3-512dba1ce4ae
invoke_action
{""timestamp"":""2012-05-08 13:47:27""}
=======================

【问题讨论】:

    标签: ruby csv


    【解决方案1】:

    试试

    CSV.foreach(csv_file_path, :quote_char => "\'")
    

    【讨论】:

    • 或者您可以gsub '""', '"' 以获得正常的csv和JSON
    • 这将破坏那些没有“非法引用”错误的行。编辑了问题。
    【解决方案2】:

    我认为最简单的方法是使用双 gsub

    require 'csv'
    line = "1336481227,178.108.171.183,3.2.0,9700132ccc02e12a,c083b5d2-ec92-486f-a5b3-512dba1ce4ae,invoke_action,\"{\"\"timestamp\"\":\"\"2012-05-08 13:47:26\"\",\"\"a\"\":\"\"b\"\"}\""
    line.gsub!('""', '%tmp%')
    csv = CSV.new(line).each.map do |line|
      line.map do |value|
        value.gsub!('%tmp%', '""')
        value
      end
    end
    
    puts csv.inspect
    # => [["1336481227", "178.108.171.183", "3.2.0", "9700132ccc02e12a", "c083b5d2-ec92-486f-a5b3-512dba1ce4ae", "invoke_action", "{\"\"timestamp\"\":\"\"2012-05-08 13:47:26\"\",\"\"a\"\":\"\"b\"\"}"]]
    

    【讨论】:

      猜你喜欢
      • 2019-11-15
      • 2014-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-22
      • 2022-11-23
      • 2016-11-08
      • 1970-01-01
      相关资源
      最近更新 更多