2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

"invalid byte sequence in UTF-8 (ArgumentError)" が起きた場合に、具体的にどのような不正なバイト列が含まれているのか調べる

Last updated at Posted at 2025-04-25

文字列がすべてひらがなで構成されているかを調べるメソッドを定義しました。

def all_hiragana?(str) = str.match?(/\A\p{Hiragana}+\z/)

all_hiragana?('もぐたろう')
#=> true

all_hiragana?('もぐタロー')
#=> false

# \x というバックスラッシュ記法で 16 進数の表現に変換しても、結果は同じ。
'もぐたろう'.b
#=> "\xE3\x82\x82\xE3\x81\x90\xE3\x81\x9F\xE3\x82\x8D\xE3\x81\x86"

all_hiragana?("\xE3\x82\x82\xE3\x81\x90\xE3\x81\x9F\xE3\x82\x8D\xE3\x81\x86")
#=> true

このメソッドにある文字列を渡すと invalid byte sequence in UTF-8 (ArgumentError) というエラーが発生します。

find_invalid_bytes("\xE3\x82\x82\x82\xAE\xE3\x81\x9F\x82\xEB\xE3\x81\x86")
# invalid byte sequence in UTF-8 (ArgumentError)

これは UTF-8 として不正なバイト列が含まれていることを示しています。しかし、具体的にどのバイト列が不正なのかはエラーメッセージからは分かりません。それを調べたいです。

方法

String#scrub という不正なバイト列を置き換えるためのメソッドを使用します。

def find_invalid_bytes(str)
  invalid_bytes = []

  str.scrub do |bytes|
    invalid_bytes << bytes

    # ブロックを渡す場合、
    # 不正なバイト列を置き換える文字列を戻り値で必ず指定する必要がある。
    '?'
  end

  invalid_bytes
end

先ほどエラーになった文字列をこの find_invalid_bytes に渡すと、不正なバイト列を返します。

find_invalid_bytes("\xE3\x82\x82\x82\xAE\xE3\x81\x9F\x82\xEB\xE3\x81\x86")
#=> ["\x82", "\xAE", "\x82", "\xEB"]

これは実は Shift_JIS で「ぐ」と「ろ」を表すバイト列でした。

invalid_str = ["\x82", "\xAE", "\x82", "\xEB"].join
invalid_str.force_encoding(Encoding::Shift_JIS).encode(Encoding::UTF_8)
#=> "ぐろ"

'ぐ'.encode(Encoding::Shift_JIS)
#=> "\x{82AE}"
'ろ'.encode(Encoding::Shift_JIS)
#=> "\x{82EB}"

バージョン情報

$ ruby -v
ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +PRISM [arm64-darwin24]

参考

Ruby リファレンス

過去に書いた Ruby と文字コードに関する記事

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?