15

I have the following string - it's not exactly comma separated but has the same effect as a csv dataset:

response = "Date;Amount;Account;User\n2014-12-01;12.01;abcxyz;user1\n2014-12-01;10.09;fine;user2\n\r\n\t\t\r\n"

I tried running the following to parse it:

CSV.parse(response, :col_sep => ";", :row_sep => :auto) 

but I get the following error:

CSV::MalformedCSVError: Unquoted fields do not allow \r or \n

Any idea why this would be happening?

I also tried doing a response.gsub!("\t", "") to see if that was the issue, but it didn't seem to help.

3
  • I just noticed that the CSV.new documentation mentions :auto as a supported value for row_sep, but not col_sep. Because it's picking up this whitespace, it stays there, and you get this error because the fields weren't quoted. Commented Dec 20, 2014 at 7:20
  • Sorry typed it backwards, but still getting the same error Commented Dec 20, 2014 at 7:23
  • I think it's because you swapped row_sep and col_sep without swapping the ; and whitespace characters in response. Commented Dec 20, 2014 at 7:33

3 Answers 3

16

I got it work with the use of #strip :

require 'csv'

response = "Date;Amount;Account;User\n2014-12-01;12.01;abcxyz;user1\n2014-12-01;10.09;fine;user2\n\r\n\t\t\r\n"

CSV.parse(response.strip, :col_sep => ';') do |row|
  p row
end

output :

arup$ ruby a.rb
["Date", "Amount", "Account", "User"]
["2014-12-01", "12.01", "abcxyz", "user1"]
["2014-12-01", "10.09", "fine", "user2"]
Sign up to request clarification or add additional context in comments.

1 Comment

it's working well
6

This will give you each row in an array.

CSV.parse( response.gsub( /[\r\t]/, '' ), col_sep: ";" )
=> [["Date", "Amount", "Account", "User"], ["2014-12-01", "12.01", "abcxyz", "user1"], ["2014-12-01", "10.09", "fine", "user2"], [], []]

Unless you want to merge all rows into a single line, you need to leave the \n for the parser to interpret as a new row.

Comments

1

An easy way to fix this is to replace any consecutive whitespace characters with a single newline before you parse the string. Then you can use the newline as your row separator, instead of setting it to :auto. This should make CSV parsing faster (since it takes more time for :auto to guess your delimiter), though performance is technically also negatively affected by the additional call to gsub.

CSV.parse(response.gsub(/\s+/, "\n"), col_sep: ';', row_sep: "\n")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.