I need to extract some values from a multi-line string (which I read from the text body of letters). I want to be able to feed templates for my parsing, so I can configure various emails later. I came up with the following:
text1 =
<<-eos
Lorem ipsum dolor sit amet,
Name: Pepe Manuel Periquita
Email: pepe@manuel.net
Sisters: 1
Brothers: 3
Children: 2
Lorem ipsum dolor sit amet
eos
pattern1 = {
:exp => /Name:[\s]*(.*?)$\s*
Email:[\s]*(.*?)$\s*
Sisters:[\s]*(.*?)$\s*
Brothers:[\s]*(.*?)$\s*
Children:[\s]*(.*?)$/mx,
:blk => lambda do |m|
m.flatten!
{:name => m[0],
:email => m[1],
:total => m.drop(2).inject(0){|sum,item| sum + item.to_i}}
end
}
def do_parse text, pattern
data = pattern[:blk].call(text.scan(pattern[:exp]))
puts data.inspect
end
do_parse text1, pattern1
So, I define the pattern as a regular expression paired with a block to build a hash from matches. The parser simply takes the text and applies the rules, executing the block as a result of matching the regular expression with the text with validation.
, text1, ( ). , "". , ...
?
/ ?
Tonttu, :
pattern2 = {
:exp => /^(.+?):\s*(.+)$/,
:blk => lambda do |m|
r = Hash[m.map{|x| [x[0].downcase.to_sym, x[1]]}]
{:name => r[:name],
:email => r[:email],
:total => r[:children].to_i + r[:brothers].to_i + r[:sisters].to_i}
end
}