Reputation: 641
I'm trying to use square brackets '[]' as a row separator in a CSV file. I must use this exact format for this project (output needs to match LEDES98 law invoicing format exactly).
I'm trying to do this:
CSV.open('output.txt', 'w', col_sep: '|', row_sep: '[]') do |csv|
#Do Stuff
end
But Ruby won't take row_sep: '[]'
and throws this error:
lib/ruby/1.9.1/csv.rb:2309:in `initialize': empty char-class: /[]\z/ (RegexpError)
I've tried escaping the characters with /'s, using double quotes, etc, but nothing has worked yet. What's the way to do this?
Upvotes: 3
Views: 1360
Reputation: 27855
The problem is in CSV#encode_re
: the parameter row_sep: "|[]\n"
is converted to a Regexp.
What can redefine this method:
class CSV
def encode_re(*chunks)
encode_str(*chunks)
end
end
CSV.open('output.txt', 'w', col_sep: '|', row_sep: "|[]\n"
) do |csv|
csv << [1,2,3]
csv << [4,5,6]
end
The result is:
1|2|3|[]
4|5|6|[]
I found no side effect, but I don't feel comfortble to redefine CSV, so I would recommend to create a new CSV-variant:
#Class to create LEDES98
class LEDES_CSV < CSV
def encode_re(*chunks)
encode_str(*chunks)
end
end
LEDES_CSV.open('output.txt', 'w', col_sep: '|', row_sep: "|[]\n"
) do |csv|
csv << [1,2,3]
csv << [4,5,6]
end
Then you can use the 'original' CSV and for LEDES-files you can use the LEDES_CSV.
Upvotes: 1
Reputation: 27855
I just tried
require 'csv'
#Create LEDES98
CSV.open('output.txt', 'w', col_sep: '|', row_sep: '[]') do |csv|
csv << [1,2,3]
csv << [4,5,6]
end
and I got
1|2|3[]4|5|6[]
Which csv/ruby-version do you use? My CSV::VERSION
is 2.4.7, my ruby version is 1.9.2p290 (2011-07-09) [i386-mingw32].
Another remark: If I look at the example files in http://www.ledes.org/ then you need additional newlines. I would recommed to use:
require 'csv'
#Create LEDES98
CSV.open('output.txt', 'w', col_sep: '|', row_sep: "[]\n") do |csv|
csv << [1,2,3,nil]
csv << [4,5,6,nil]
end
Result:
1|2|3|[]
4|5|6|[]
The additional nils gives you the last |
before the [].
I tested on another computer with ruby 1.9.3p194 (2012-04-20) [i386-mingw32] and get the same error.
I researched a bit and can isolate the problem:
p "[]" #[]
p "\[\]" #[] <--- Problem
p "\\[\\]" #\\[\\]
You can't mask the [
. If you mask it once, Ruby produces [
(without the mask sign). If you mask it twice, you mask only the \, not the ].
Upvotes: 0
Reputation: 3072
Given an input string of the form
s = "[cat][dog][horsey\nhorse]"
you could use something like
s.scan(/\[(.*?)\]/m).flatten
which would return ["cat", "dog", "horsey\nhorse"]
and process that with CSV module.
Upvotes: 0