Как исправить ошибку чтения CSV с точкой с запятой в конце строки - PullRequest
1 голос
/ 22 мая 2019

Я хочу использовать класс Ruby CSV для чтения файла:

Файл для чтения выглядит так:

CM_ SG_ 1325 XXX_Address "XXX address";
CM_ SG_ 612 YYY_MsgCounter "incremented by 1 each time a 
message has been transmitted";

Мой рубиновый код:

#!/usr/bin/env ruby
require 'pp'
require 'csv'
CSV.foreach(ARGV[0],:col_sep=>" ") do |row|
    pp row
end

Это ошибка, которую я получаю:

C:/ruby-2.3.3-x64-mingw32/lib/ruby/2.3.0/csv.rb:1898:in `block in shift': Unclosed quoted field on l
ine 1. (CSV::MalformedCSVError)
        from C:/ruby-2.3.3-x64-mingw32/lib/ruby/2.3.0/csv.rb:1805:in `loop'
        from C:/ruby-2.3.3-x64-mingw32/lib/ruby/2.3.0/csv.rb:1805:in `shift'
        from C:/ruby-2.3.3-x64-mingw32/lib/ruby/2.3.0/csv.rb:1747:in `each'
        from C:/ruby-2.3.3-x64-mingw32/lib/ruby/2.3.0/csv.rb:1131:in `block in foreach'
        from C:/ruby-2.3.3-x64-mingw32/lib/ruby/2.3.0/csv.rb:1282:in `open'
        from C:/ruby-2.3.3-x64-mingw32/lib/ruby/2.3.0/csv.rb:1130:in `foreach'
        from test.rb:4:in `<main>'

Если я уберу точку с запятой в конце строки, я получу это:

["CM_", "SG_", "1325", "XXX_Address", "XXX address"]
["CM_",
 "SG_",
 "612",
 "YYY_MsgCounter",
 "incremented by 1 each time a \r\nmessage has been transmitted"]

что я и ожидал увидеть.

Я предполагаю, что проблема в том, что CSV не нравится точка с запятой против цитаты. Есть ли способ сжать эту точку с запятой, используя опцию CSV, или дать CSV поток, в котором я уже отжал его?

Разъяснения:

Я прошу прощения за то, что не указывал это изначально, , но не каждая строка будет иметь точку с запятой .

Кроме того, я хотел бы поблагодарить Tin Man за внесение лишних правок в мой пост, чтобы увеличить его счет. ;)

Ответы [ 2 ]

1 голос
/ 22 мая 2019

Поскольку вы знаете, что каждая строка заканчивается точкой с запятой, просто укажите разделитель строк, например

CSV.foreach(ARGV[0],col_sep:" ", row_sep:";").to_a
#=> [["CM_", "SG_", "1325", "XXX_Address", "XXX address"], 
#    ["CM_", "SG_", "612", "YYY_MsgCounter", "incremented by 1 each time a message has been transmitted"]]

Вы потеряете новую строку в строке, даже не зная, насколько это важно

ПРИМЕЧАНИЕ. Согласно моему обсуждению с @iGian, это решение для ruby ​​<2.6.0, а его решение для> = 2.6.0

0 голосов
/ 22 мая 2019

Попробуйте, для Ruby 2.6.1 :

require 'pp'
require 'csv'

CSV.foreach(ARGV[0], col_sep: ' ', row_sep: :auto, liberal_parsing: {double_quote_outside_quote: true} ) do |row|
    pp row
end

Кажется, работает. Смотрите эту проблему: https://github.com/ruby/csv/issues/66

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...