【问题标题】:Extract values from a text body in Ruby从 Ruby 中的文本正文中提取值
【发布时间】:2011-01-26 01:08:19
【问题描述】:

我需要从多行字符串(我从电子邮件的正文中读取)中提取一些值。我希望能够将模式提供给我的解析器,以便以后可以自定义不同的电子邮件。我想出了以下几点:

#!/usr/bin/env ruby

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
}

# Scan on text returns 
#[["Pepe Manuel Periquita", "pepe@manuel.net", "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=>"pepe@manuel.net", :total=>6, :name=>"Pepe Manuel Periquita"}

因此,我将模式定义为与块配对的正则表达式,以从匹配项中构建散列。 “解析器”简单地获取文本并应用规则,方法是在将正则表达式与扫描文本匹配的结果上执行块。

目前我必须使用 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
}

【问题讨论】:

    标签: ruby regex text extract extraction


    【解决方案1】:

    也许这样的东西足够通用?

    pp Hash[*text1.scan(/^(.+?):\s(.+)$/).map{|x|
         [x[0].downcase.to_sym, x[1]]
       }.flatten]
    
    =>
    {:sisters=>"1",
     :brothers=>"3",
     :children=>"2",
     :name=>"Pepe Manuel Periquita",
     :email=>"pepe@manuel.net"}
    

    【讨论】:

    • 这很好,但是如何将表达式应用于匹配的值以导出其他值,例如我的示例中的总计,它是三个字段的总和?
    猜你喜欢
    • 2019-09-14
    • 2012-06-26
    • 2012-07-12
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    • 2020-08-07
    • 1970-01-01
    相关资源
    最近更新 更多