Rubyを勉強しているものです。いつもお世話になります。
http://www.valor.com.br/valor-data/tabela/5823/frango
というホームページから特定の位置の情報(/\d,\d\d/)を取りたいです。
Frango resfriado の行の Mín. Méd. Máx. の3つの値。
降りて行って、
Abatido Resfriado 4,10
Peito 5,20
Coxa 4,30
Vivo - Paralelo (*) 2,50
の4行に渡る4つの値。
一応、一日かけて以下のようなコードを書いてみました。機能はしているのかな?と思っていますが、これでいいのかな感が強く、出来た感が湧いてきません。多くの項目を正規表現で捕らえたい時のやりかたってこんなんでいいのでしょうか?他にいいロジックや方法はあるのでしょうか?
ご指導、よろしくお願い致します。(たのしいRubyから派生させましたので不要なコードも混じっています。。すみません。)
Ruby
1class Frango 2 require 'open-uri' 3 4 def self.market_today(url = "http://www.valor.com.br/valor-data/tabela/5823/frango", 5 pattern = Regexp.new('Frango resfriado')) 6 max_matches = 10 7 matches = 0 8 price = [] 9 urlcontents = open(url) 10 urlcontents.each_line do |line| 11 next if /^\s*$/ =~ line 12 next if /^#/ =~ line 13 if pattern =~ line 14 matches += 1 15 puts "マッチした行#{matches}行め" 16 puts $~ # $~ は最後に実行したパターンマッチに関する情報 17 puts $& # $& は最後に実行したパターンマッチでマッチした文字列。今回はマッチした文字列だけで十分 18 #puts line 19 20 after_pattern = $' # マッチした文字列'Frango resfriado' より 1つめの/\d,\d\d/ 21 after_pattern =~ /(\d,\d\d)/ 22 price << $& 23 24 after_pattern = $' # マッチした文字列'Frango resfriado' より 2つめの/\d,\d\d/ 25 after_pattern =~ /(\d,\d\d)/ 26 price << $& 27 28 after_pattern = $' # マッチした文字列'Frango resfriado' より 3つめの/\d,\d\d/ 29 after_pattern =~ /(\d,\d\d)/ 30 price << $& 31 32 after_pattern = $' # 3つめの/\d,\d\d/より 33 after_pattern =~ /(Abatido Resfriado)/ # Abatido Resfriado のマッチするとこまで飛んで 34 after_pattern = $' # その/\d,\d\d/ とマッチング 35 after_pattern =~ /(\d,\d\d)/ 36 price << $& 37 38 after_pattern = $' # そこから 39 after_pattern =~ /(Peito)/ # Peito のマッチするとこまで飛んで 40 after_pattern = $' # その/\d,\d\d/ とマッチング 41 after_pattern =~ /(\d,\d\d)/ 42 price << $& 43 44 after_pattern = $' # そこから 45 after_pattern =~ /(Coxa)/ # Coxa のマッチするとこまで飛んで 46 after_pattern = $' # その/\d,\d\d/ とマッチング 47 after_pattern =~ /(\d,\d\d)/ 48 price << $& 49 50 after_pattern = $' # そこから 51 after_pattern =~ /(Vivo - Paralelo)/ # Vivo - Paralelo のマッチするとこまで飛んで 52 after_pattern = $' # その/\d,\d\d/ とマッチング 53 after_pattern =~ /(\d,\d\d)/ 54 price << $& 55 end 56 break if matches >= max_matches 57 end 58 print price, "\n" 59 end 60end 61 62Frango.market_today 63
また、どうしても、DRYに(挑戦)したくいじったコードが以下になりますが、取得順序が思いの順番でなくなりました。。わからなくなりました。
Ruby
1class Frango 2 require 'open-uri' 3 4 def self.market_today(url = "http://www.valor.com.br/valor-data/tabela/5823/frango", 5 patterns = /(Frango resfriado|Abatido Resfriado|Peito|Coxa|Vivo - Paralelo)/) 6 7 price = [] 8 urlcontents = open(url) 9 regexp = Regexp.new(patterns) 10 urlcontents.each_line do |line| 11 12 if regexp =~ line 13 14 puts $~ # $~ は最後に実行したパターンマッチに関する情報 15 puts $& # $& は最後に実行したパターンマッチでマッチした文字列。今回はマッチした文字列だけで十分 16 #puts line 17 18 3.times do 19 after_pattern = $' # マッチした文字列'Frango resfriado' より 1つ2つ3つめの/\d,\d\d/ 20 after_pattern =~ /(\d,\d\d)/ 21 price << $& 22 end 23 24 4.times do 25 after_pattern = $' # 3つめの/\d,\d\d/より 26 #after_pattern =~ /(Abatido Resfriado)/ # Abatido Resfriado のマッチするとこまで飛んで 27 after_pattern = $' # その/\d,\d\d/ とマッチング 28 after_pattern =~ /(\d,\d\d)/ 29 price << $& 30 end 31 end 32 end 33 print price, "\n" 34 end 35end 36 37Frango.market_today 38
長たらしい質問になってしまいましたが、こうした方がいい(こうすべきだ)、ああした方がいい(ああすべきだ)、というのがあれば教えてください。よろしくお願い致します。失礼します。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/09/09 09:43