what I would like to avoid is to write something like this
(that works)
line =~ /(\w*)=([0-9A-Za-z -.:]),([0-9A-Za-z -.:]),([0-9A-Za-z
-.:]),([0-9]),([0-9]),([0-9]),([0-9]),([0-9]),([0-9]),([0-9]),([0-9]),([0-9]),([0-9]*)/
I wanted to this in one line but in a more mainable way, otherwise I
could always pars the string char by char.
If you don’t actually need to match the data against a pattern, then
just use
line.split(’,’)
If you only want to proceed if the line is “valid”, then write a
suitable regexp pattern to validate it. There are plenty of shortcuts.
For example, \d is the same as [0-9]. {n} means repeat the preceeding
element exactly n times. So:
case line
when /^(\w*)=([^,]*),(\d+(,\d+){9})$/
key1 = $1
key2 = $2
numbers = $3.split(/,/).collect { |n| n.to_i }
# or: numbers = $3.scanf("%d %d %d %d %d %d %d %d %d %d") if you
prefer
else
puts “Invalid line!”
end
That matches word=string,n,n,n,n,n,n,n,n,n,n
Furthermore you can substitute patterns you use repeatedly:
WORD = “[0-9A-Za-z -.:]*”
…
when /^(#{WORD})=(#{WORD}),(#{WORD}),(\d+(,\d+){9})$/o
(//o means that the regexp is built only once, the substitutions aren’t
done every time round)
You can also use extended syntax to make the RE more maintainable:
VALID_LINE = %r{ ^
(\w*) = # key ($1)
(#{WORD}), # format ($2)
(\d+), # size ($3)
(\d+) # sample rate ($4)
$ }x
if VALID_LINE =~ line
…
end
You can also do groupings which don’t capture data using (?: … )
Compact enough?