質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

2回答

618閲覧

File.openの中の変数を外で使えない

kazuyakazuya

総合スコア193

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2019/07/24 14:17

編集2019/07/24 14:42

ファイルの中にあるHTMLコードを取りだすプログラムを作っています。
search_html.erbという名前のファイルにHTMLコードが詰まっています。
(あまりに巨大すぎるためHTMLコードは張っていません。)

ruby

1File.open("search_html.rb","r",encoding: "UTF-8") do |file| #html格納ファイルを開く 2 file.each_line do |line| #行単位で読み込む 3 matching_class = line.match(/"/questions/.{1,9}"/) #正規表現条件 4 puts matching_class unless matching_class == nil #正規表現にマッチングした場合だけ表示(そうしないと空のものも出力されてしまう) 5 end 6end 7

上記のコードは

url

1<a href="/questions/158840" title="rubyでslack apiを使ってbotを動かそうとしたが、`require&amp;#039;: cannot load such file -- slack-api (LoadError)とエラーが出る">rubyでslack apiを使ってbotを動かそうとしたが、`require&#039;: cannot load such file -- slack-api (LoadError)とエラーが出る</a>

aタグのhrefが"/questions/数字"にマッチングしたものを出力するプログラムです。

ruby

1"/questions/input" 2"/questions/451" 3"/questions/11650" 4"/questions/159979" 5"/questions/44507" 6"/questions/29835" 7"/questions/23822" 8"/questions/22259" 9"/questions/349" 10"/questions/184271" 11"/questions/88553" 12"/questions/5449" 13"/questions/1937" 14"/questions/167766" 15"/questions/106419" 16"/questions/61837" 17"/questions/200865" 18"/questions/96483" 19"/questions/71396" 20"/questions/130792" 21"/questions/158840"

このような感じで成功しています。(teratailのパス)

ruby

1File.open("search_html.rb","r",encoding: "UTF-8") do |file| #html格納ファイルを開く 2 file.each_line do |line| #行単位で読み込む 3 matching_class = line.match(/"/questions/.{1,9}"/) #正規表現条件 4 puts matching_class unless matching_class == nil #正規表現にマッチングした場合だけ表示(そうしないと空のものも出力されてしまう) 5 end 6end 7

ここから本題
上記のmatching_class変数にパスが格納されています。
この変数をブロックの外で使おうとすると

ruby

1File.open("search_html.rb","r",encoding: "UTF-8") do |file| #html格納ファイルを開く 2 file.each_line do |line| #行単位で読み込む 3 matching_class = line.match(/"/questions/.{1,9}"/) #正規表現条件 4 puts matching_class unless matching_class == nil #正規表現にマッチングした場合だけ表示(そうしないと空のものも出力されてしまう) 5 end 6end 7puts matcing_class ←ここ!ブロックの外で呼び出す。

すると何も表示されないです。

ruby

1matching_class = nil 2File.open("search_html.rb","r",encoding: "UTF-8") do |file| #html格納ファイルを開く 3 file.each_line do |line| #行単位で読み込む 4 matching_class = line.match(/"/questions/.{1,9}"/) #正規表現条件 5 puts matching_class unless matching_class == nil #正規表現にマッチングした場合だけ表示(そうしないと空のものも出力されてしまう) 6 end 7end 8puts matcing_class ←ここ!ブロックの外で呼び出す。

ブロックの外であらかじめmatching_classを定義した場合も
試したのですが駄目でした。
何が原因なのでしょうか?
ファイルを扱っているブロックだからなのでしょうか?
分からないのでお願いします。

念のため全コード

ruby

1require 'net/http' 2require 'uri' 3puts "検索キーワードを入れてください" 4search_word = STDIN.gets 5uri = URI.parse("https://teratail.com/search?q=#{search_word}") 6http= Net::HTTP.new("teratail.com",443) 7http.use_ssl = true 8http.verify_mode = OpenSSL::SSL::VERIFY_NONE 9response = http.get(uri) 10html_body = response.body 11puts "---ステータスコード---" 12puts response.code 13response.each do |name,value| 14 puts name + ":" + value 15end 16puts "ヘッダー終了" 17File.open("search_html.rb","w") do |io| 18 io.write(html_body) 19end 20puts "マッチングした場所" 21matching = nil 22File.open("search_html.rb","r",encoding: "UTF-8") do |file| 23 file.each_line do |line| 24 matching_class = line.match(/"/questions/.{1,9}"/) 25 puts matching_class unless matching_class == nil 26 end 27end

ruby

1require 'net/http' 2require 'uri' 3puts "検索キーワードを入れてください" 4search_word = STDIN.gets 5uri = URI.parse("https://teratail.com/search?q=#{search_word}") 6http= Net::HTTP.new("teratail.com",443) 7http.use_ssl = true 8http.verify_mode = OpenSSL::SSL::VERIFY_NONE 9response = http.get(uri) 10html_body = response.body 11puts "---ステータスコード---" 12puts response.code 13response.each do |name,value| 14 puts name + ":" + value 15end 16puts "ステータスコード終了" 17File.open("search_html.rb","w") do |io| 18 io.write(html_body) 19end 20puts "マッチングした場所" 21a = [] 22File.open("search_html.rb","r",encoding: "UTF-8") do |file| 23 file.each_line do |line| 24 matching_class = line.match(/"/questions/.{1,9}"/) 25 #puts matching_class unless matching_class == nil 26 a.push(matching_class) unless matching_class == nil 27 end 28end 29 30a.each do |b| 31 puts b 32end

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

外で予め定義しておいたらブロックの外で使えました。

提示されたソースでは、最後に実行された matching_class = line.match の結果が参照され、それはおそらく matching_class = "</html>".match ですから nil が入って、それが参照された、ということですね

初めの定義で mattching_class="" にしておくと、終わったら nil になっているというのが確認できると思います。

matching_classes = []
しておいて
matching_classes << matching_class if matching_class
して、
マッチした全てを見る、ということでは?

投稿2019/07/24 14:42

winterboum

総合スコア23329

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuyakazuya

2019/07/24 14:45

ありがとうございます! この回答をみる直前で 配列にすることで回避できることがわかりました。
guest

0

自己解決

配列に格納することで回避できました。
追記しておきます。

投稿2019/07/24 14:41

kazuyakazuya

総合スコア193

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問