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

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

新規登録して質問してみよう
ただいま回答率
85.35%
ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

Ruby

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

ファイルI/O

ファイルI/Oは、コンピューターにおけるファイルの入出力です。これは生成/削除やファイルを読み込んだり、出力をファイルに書き込むようなディレクトリやファイルの運用を含みます。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

2回答

1042閲覧

正規表現で抽出した文字列をテキストファイルに書き込みたい

0k0rait

総合スコア5

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

Ruby

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

ファイルI/O

ファイルI/Oは、コンピューターにおけるファイルの入出力です。これは生成/削除やファイルを読み込んだり、出力をファイルに書き込むようなディレクトリやファイルの運用を含みます。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

0クリップ

投稿2020/06/20 16:13

編集2020/06/20 16:14

前提・実現したいこと

オンライン小説のテキストファイルを読み込み、特定の行(「」『』で囲まれた行)だけを正規表現で抜き出し、新規で作ったテキストファイルに抜き出した行を書き込むプログラムを組みたいです。言語はRubyです。

発生している問題・エラーメッセージ

抜き出したテキストのファイル書き込みが行われない。

該当のソースコード

# encoding: UTF-8 File.open("結合結果.txt","r",:encoding => Encoding::UTF_8, :invalid => :replace, :undef => :replace) do |io| while line = io.gets episode = line.chomp! File.open("台詞集.txt","w"){|f| episode.scan(/(「|『)([a-zA-z]|[^a-zA-z]*)(」|』)/) do |a,b,c| serif = a + b + c f.write serif end } end end

以下のような結果が新規で作ったテキストに書き込まれていてほしい。

「○○○~」←最初の行
『○○○~』



『○○○~』
「○○○~」←最後の行

試したこと

# encoding: UTF-8 File.open("結合結果.log","r",:encoding => Encoding::UTF_8, :invalid => :replace, :undef => :replace) do |io| while line = io.gets episode = line.chomp! #puts episode episode.scan(/(「|『)([a-zA-z]|[^a-zA-z]*)(」|』)/) do |a,b,c| serif = a + b + c puts serif end end end

puts serif をしたところ、実際に「」『』で囲まれた文章が抜き出せていました。

補足情報(FW/ツールのバージョンなど)

 
Rubyのバージョンは2.5.7です。
よろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

こんなんでどうでしょう。

Ruby

1# encoding: UTF-8 2 3File.open("結合結果.log","r",:encoding => Encoding::UTF_8, :invalid => :replace, :undef => :replace) do |io| 4 File.open("台詞集.txt", "w") do |f| 5 io.each_line do |line| 6 episode = line.chomp 7 episode.scan(/([「『])(.*?)([」』])/) do |a,b,c| 8 serif = a + b + c 9 f.puts serif 10 end 11 end 12 end 13end

修正点

  • 書き込み用のFile.openをwhileループの中で行なうと、1行読み込むたびに「書き込みモード」でファイルを開きなおすので、以前の内容が上書きされて失われてしまう。対策は、whileループの外に出すこと。
  • line.chomp!で改行を取り除いているため、最終行に改行が付いていないと(元の文字列ではなく)nilが返る。対策は、line.chompを使う。
  • 正規表現に含まれる[a-zA-z]は意味不明。[a-zA-Z](大小英字1文字)の間違い? それはともかく、ここでは、「カギカッコ類に挟まれた(閉じカギカッコを含まない)文字列」が取得できればいいので、非貪欲なマッチをする.*?を使った。これで、1行に複数の「……」「……」が並んでいても個別に取得できる。
  • 両端のカギカッコを示す正規表現は、対応する記号が増えてもいいように**([「『])([」』])に変更**。全角のを追加し足りしたくなった場合に備えて。
  • ファイルへの出力にf.writeを使うと、line.chompで改行を取り除いているので改行しない。期待する結果を見るに改行が求められているので、自動改行する**f.putsに変更**。
  • while line = io.getsio.each_line do |line|に変更。

投稿2020/06/20 17:21

Daregada

総合スコア11990

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

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

0k0rait

2020/06/21 02:11

正規表現のミスまで見ていただきありがとうございます!個人的に()も取り出したいと思っていたので非常に助かりました。
Daregada

2020/06/21 02:23

別に、'(「|『|()'と書いてもいいんですけどね。長くなりそうだから。 あと、前後のカッコの種類を合わせる('「'で始まるなら'」'だけを終わりと見なす)ことも可能ですが、長くなるので勘弁してください。
guest

0

ベストアンサー

ループの中で毎回ファイルをオープンして上書きしているので、最後に上書きされた行しかファイルには残っていないということでは?

投稿2020/06/20 16:25

otn

総合スコア85901

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

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

0k0rait

2020/06/20 16:37

回答で指摘していただいたことをプログラムで実践してみたら一行ずつ書き込むことができました!ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問