Мне нужно извлечь некоторые значения из многострочной строки (которую я прочитал из текстового тела писем). Я хочу, чтобы иметь возможность кормить шаблоны для моего синтаксического анализа, поэтому я могу настроить различные электронные письма позже. Я придумал следующее:Извлечь значения из текстового тела в Ruby
#!/usr/bin/env ruby
text1 =
<<-eos
Lorem ipsum dolor sit amet,
Name: Pepe Manuel Periquita
Email: [email protected]
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
}
# Scan on text returns
#[["Pepe Manuel Periquita", "[email protected]", "1", "3", "2"]]
def do_parse text, pattern
data = pattern[:blk].call(text.scan(pattern[:exp]))
puts data.inspect
end
do_parse text1, pattern1
# ./text_parser.rb
# {:email=>"[email protected]", :total=>6, :name=>"Pepe Manuel Periquita"}
Итак, я определить шаблон как регулярное выражение сопряженного с блоком для создания хэша от спичек. «Парсер» просто берет текст и применяет правила, выполняя блок в результате сопоставления регулярного выражения с текстом с проверкой.
На данный момент мне приходится разбирать электронные письма с форматом, как показано в тексте1, но позже я хотел бы как можно проще добавить шаблоны для извлечения данных из разных электронных писем (формат этих писем будет исправлен для каждого типа) , Поэтому я хотел бы упростить шаблон, перемещающийся как можно больше к «парсеру». Вышеприведенный код работает и извлекает данные, но большая часть работы находится по шаблону ...
Это правильный путь?
Может быть упрощено или вы думаете о другом/лучшем решении этой проблемы?
Update
Я обновил парсер следующее решение 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
}
Это очень приятно, но как бы вы применили выражения для согласованных значений для получения других значений, таких как общее число в моем примере, которое представляет собой сумму трех полей? – Miquel