Rubyで全角文字列(外字除く)であるかを判断する方法

かなりはまったのでメモ。
要件

  • 全角文字以外を入力チェックで弾く
  • JIS X 0208の1区から8区および16区から84区(すなわち外字を除くJIS第2水準漢字までの全角文字)を有効とする
  • デフォルト文字コードutf-8

で、以下の通り実現

require 'kconv'
def zenkaku_only? str
  str.toeuc.split(//e).each{|s|
    return false unless (s =~ /[\xa1-\xa8][\xa1-\xfe]/n) or (s =~ /[\xb0-\xcf][\xa1-\xfe]/n) or (s =~ /[\xd0-\xf4][\xa1-\xfe]/n)
  }
  return true
end

ポイント

  1. utf-8のままだと第1水準や第2水準の漢字が規則正しく並んでいないので、kconvのtoeucメソッドでeuc-jpに変換(sjisでも可)
  2. split関数で一文字ずつ取り出すとき、正規表現文字コードオプションをeucにする(//eのところ)

それにしても、なんかダサい・・・orz。正規表現一発でなんとかならないかと1日考えましたがギブアップです。もっとよいコードを思いついたらまた書きます。