テキスト解析関数
2007-12-11: これも改良するかな
関数の引数の指定方法は、結局最初に戻ってしまいました。
ただ、指定する値の接頭辞に xpath:// もしくは regexp:// を
付けて、動作を分けるという特殊な感じになりました。
正規表現指定と xpath 指定の設定を分けても良かったのだけれども、
設定項目を増やすのだけは嫌だったので、一緒に。
opt のハッシュキーは、Symbol から String へ変更。
require 'rubygems' require 'hpricot' def extract_text(text, opt) # argument no check prefix_xpath = %q{^\s*xpath://} prefix_regexp = %q{^\s*regexp://} case opt['record_fetch'] when /#{prefix_xpath}(.+)/ xpath = $1 doc = Hpricot(text) record = doc.search(xpath).collect {|r| r.to_s} when /#{prefix_regexp}(.+)/ regexp = $1 record = text.scan(/#{regexp}/m) else return [] end item_xpath = Hash[*opt['field_fetch'].map {|k, v| [k, $1] if v =~ /#{prefix_xpath}(.+)/}.compact.flatten] item_regexp = Hash[*opt['field_fetch'].map {|k, v| [k, $1] if v =~ /#{prefix_regexp}(.+)/}.compact.flatten] data = [] record.each {|r| item = {} if item_regexp.size item_regexp.each_pair {|key, val| item[key] = r.match(/#{val}/m).to_a[1] } end if item_xpath.size doc = Hpricot(r) item_xpath.each {|key, val| elem = doc.at(val) 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
- サンプル
config = YAML.load(<<'EOD') record_fetch: regexp://<item>.+?</item> field_fetch: name: regexp://<name>(.+?)</name> date: regexp://<date>(.+?)</date> comment: xpath://comment id: regexp://<id>(.+?)</id> after_hook: | item['comment'] = item['comment'].match(/>(.+?)<\//).to_a[1] EOD data = extract_text(@text, config)