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

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

ただいまの
回答率

88.35%

rubyで文字を置換するコードを書きたいです

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 475

otakurounin

score 21

rubyで、新字体を旧字体に置換するコードを書きたいです。
とりあえず、置換について解説しているサイトを参考に書いたのが、

hash = {'伝'=>'傳','礼'=>'禮'}
"左伝における礼".gsub!(/[伝]|[礼]/, hash)
というコードです。
これは期待通りに実行できました。
ただ、改善したい点として、
まず、置換すべき字を、ハッシュ内と正規表現部分に二度書いているのは二度手間なのでハッシュのキーの文字を自動的に置換するようにできないでしょうか。
次に、実際に使う際には置換対象データが数万字以上の規模になると予想されるので、上に書いたようなコードではなく、ファイルからデータを読み込む、

hash = {'伝'=>'傳','礼'=>'禮'}
a=[]
File.open("saden.txt", "r"){|f|
f.each_line{|line|
a<<line.gsub(/[伝]|[礼]/, hash)}
}
File.open("saden_new.txt", "w"){|f|
a.each{|s| puts(s)}
}
というようにファイルから一行ずつ読み込んで処理する形にしたいのす。
上記のコードも実行できましたが、「ファイルを開いて、処理して、書き込む」という一連の処理について解説したサイトが見当たらず、読み込みについて解説したサイトと書き込みについて解説したサイトの内容を混ぜて書いたので、もっと効率のいい(配列を介さずに処理する)方法があるのではないかと思います。
また、ハッシュも実際に使うときには数百字以上になるはずなので、これも別ファイルにできないものかと思います。
以上の点のほか、お気づきの点がありましたら教えてください。

ここで、処理後の文字列を新しいファイルに書き込むにはどうしたらいいのでしょうか。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

こんな感じで。

CONV = {'伝'=>'傳','礼'=>'禮'}
CONV_REGEX = Regexp.union(CONV.keys)

open("saden_new.txt", "w") do |f|
  IO.foreach("saden.txt") do |line|
    line.gsub!(CONV_REGEX, CONV)
    f.puts line
  end
end

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/04/10 18:38

    ありがとうございます。こうすると簡単に書けますね。

    キャンセル

+1

hash の内容をファイルに保存する。
make_hash.rb

require 'yaml'

# hash 胚葉をファイルに作成する
hash = { '伝' => '傳', '礼' => '禮' }
YAML.dump(hash, File.open('data.yml', 'w'))

実行例
イメージ説明

hash 内容が data.yml に YAML 形式で保存できています。

Hasy 内容をファイルから読み込む。それをつかって、標準入力の文字を置換して 標準出力に書き込むプログラム。
それを ファイルのリダイレクトをつかって 結果を画面でなくファイルに保存する。
xx.rb

require 'yaml'

# ファイルから hash を読み込む
hash = YAML.load_file('data.yml')

loop do
  c = $stdin.getc
  break if c.nil?

  putc hash[c] || c
end

実行例
イメージ説明

data.yml を読み込みんで hash を設定します、
test.txt を 1 文字ずつ読み込み、 hash にある文字なら置換します。なければそのままを出力します。
リダイレクトすることで out.txt に保存しています。
 

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/04/11 18:19

    詳細なご回答ありがとうございます。
    これで置換データも別ファイルにできました。
    リダイレクトについては、私のターミナルでは
    演算子 '<' は、今後の使用のために予約されています。
    + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : RedirectionNotSupported
    というエラーが出て使えなかったので、置換部分は元のコードで動作確認しましたが。

    キャンセル

  • 2020/04/11 18:50

    cat test.txt | ruby xx.rb > out.txt をためしてみてください。

    キャンセル

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

  • ただいまの回答率 88.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る