テキスト抽出処理
regexp:// とか、xpath:// とかおかしな設定方法をやめました。
これである程度、テキストから情報を抽出することができる。
結果は配列にハッシュを入れたものだから、それを RSS でも、
Atom にでも入れてしまえばいい。
require 'rubygems' require 'hpricot' class Extract def Extract.match(text, opt) return [] unless opt.key?(:record) && opt.key?(:item) if opt[:record].key?(:xpath) doc = Hpricot(text) record = doc.search(opt[:record][:xpath]).collect {|r| r.to_s} elsif opt[:record].key?(:regexp) record = text.scan(/#{opt[:record][:regexp]}/m) else return [] end item_xpath = Hash[*opt[:item].map {|k, v| [k, v] if v.key?(:xpath)}.compact.flatten] item_regexp = Hash[*opt[:item].map {|k, v| [k, v] if v.key?(:regexp)}.compact.flatten] data = [] record.each {|r| item = {} if item_regexp.size item_regexp.each_pair {|key, val| item[key] = r.match(/#{val[:regexp]}/m).to_a[1] } end if item_xpath.size doc = Hpricot(r) item_xpath.each {|key, val| elem = doc.at(val[:xpath]) if elem.nil? item[key] = '' else item[key] = elem.to_s end } end if opt.key?(:after_hook) eval(opt[:after_hook]) end data << item } data end end
- テストコード
require 'pp' text =<<EOD <root> <record> <item> <name>user01</name> <id>0</id> <date>2007/11/25</date> <comment>comment01 foobar</comment> </item> <item> <name>user02</name> <id>1</id> <date>2007/11/28</date> <comment>comment02 foobar</comment> </item> <item> <name>user03</name> <id>2</id> <date>2007/11/30</date> <comment>comment03 foobar</comment> </item> </record> </root> EOD data = Extract.match(text, { 'record_fetch' => %q{xpath:///root/record/item}, }) data = Extract.match(text, { :record => { :xpath => '/root/record/item', }, :item => { :name => { :xpath => 'name/text()', }, :date => { :xpath => 'date/text()', }, :comment => { :regexp => '<comment>(.+?)</comment>', }, :id => { :xpath => 'id/text()', }, } }) pp data
- 実行結果
[{:name=>"user01",
:id=>"0",
:date=>"2007/11/25",
:comment=>"comment01 foobar"},
{:name=>"user02",
:id=>"1",
:date=>"2007/11/28",
:comment=>"comment02 foobar"},
{:name=>"user03",
:id=>"2",
:date=>"2007/11/30",
:comment=>"comment03 foobar"}]