Rubyのエラー『Encoding::UndefinedConversionError: ‘X’ to ‘Y’』の解決方法

Rubyのエラー『Encoding::UndefinedConversionError: ‘X’ to ‘Y’』の解決方法

Rubyで文字エンコーディングの変換を行う際に発生する『Encoding::UndefinedConversionError: ‘X’ to ‘Y’』のエラーについて、発生条件と解決策を詳しく説明する。

エラーの発生条件

このエラーは、あるエンコーディングから別のエンコーディングに変換する際に、変換できない文字が含まれている場合に発生する。

str = "こんにちは"
puts str.encode("ISO-8859-1")
# Encoding::UndefinedConversionError: "こんにちは" from UTF-8 to ISO-8859-1

エンコーディングを確認する

対象の文字列のエンコーディングを確認することで、問題の原因を特定できる。

str = "こんにちは"
puts str.encoding # => UTF-8

変換可能なエンコーディングを指定する

UTF-8 から ISO-8859-1 への変換はできないが、UTF-8 から Shift_JIS や EUC-JP なら変換できる。

str = "こんにちは"
puts str.encode("Shift_JIS")
puts str.encode("EUC-JP")

変換時に無効な文字を置き換える

変換できない文字を「?」や「_」などに置き換える方法。

str = "こんにちは"
puts str.encode("ISO-8859-1", invalid: :replace, undef: :replace, replace: "?")

バイト列として変換する

バイナリデータとして扱い、一旦 ASCII-8BIT に変換して処理する方法。

str = "こんにちは"
binary_str = str.encode("ASCII-8BIT")
puts binary_str.force_encoding("ISO-8859-1")

エンコーディングを統一する

ファイルのエンコーディングを統一することで、エラーを回避できる。

File.open("example.txt", "w:utf-8") { |f| f.write("こんにちは") }

エンコーディングが混在する場合の対応

複数の異なるエンコーディングが混在している場合、全体を UTF-8 に統一する。

str = File.read("example.txt", encoding: "UTF-8")
puts str.encode("UTF-8")

環境変数 LANG の確認

システムのデフォルトエンコーディングが影響していることがある。

puts ENV['LANG']

外部から読み込んだデータのエンコーディングを変換する

ファイルや API から取得したデータを適切なエンコーディングに変換する。

data = File.read("example.txt", encoding: "Windows-31J").encode("UTF-8")
puts data

まとめ

  • エンコーディングの確認を最初に行う
  • 変換できるエンコーディングを選ぶ
  • 変換時に無効な文字を置き換える
  • システムのエンコーディング設定を確認する
  • データのエンコーディングを統一する