Rubyで数値文字参照をUTF-8にする

どういうわけか書いた、数値文字参照UTF-8にするスクリプトがあったのであげてみる。完成品はラストの一行だけなんですけどねー、ねー。

$KCODE='u'

# 文字は 16bit と仮定

s1 = '人生オワタ'.unpack('U*').collect {|c| c >= 255 ? '&#' + c.to_s + ';' : c.chr }.join
s2 = '\(^o^)/'.unpack('U*').collect {|c| c >= 255 ? '&#x' + c.to_s(16) + ';' : c.chr }.join

s = s1 + s2
puts '元データ ("人生オワタ"は10進,"\(^o^)/"は16進)'
puts s
#=>人生オワタ\(^o^)/ 

puts '(1) 10進数値による数値文字参照 => UTF-8'
puts s.gsub(/&#(\d*?);/) { [$1.to_i].pack('U') }
#=>人生オワタ\(^o^)/

puts '(2) 16進数値による数値文字参照 => UTF-8'
puts s.gsub(/&#[xX]([0-9a-fA-F]{4});/) { [$1.to_i(16)].pack('U') }
#=>人生オワタ\(^o^)/

puts '(1) + (2)'
puts s.gsub(/&#(\d*?);/) { [$1.to_i].pack('U') }.gsub(/&#[xX]([0-9a-fA-F]{4});/) { [$1.to_i(16)].pack('U') }
#=>人生オワタ\(^o^)/

puts '数値文字参照 => UTF-8'
puts s.gsub(/&#(?:(\d*?)|(?:[xX]([0-9a-fA-F]{4})));/) { [$1.nil? ? $2.to_i(16) : $1.to_i].pack('U') }
#=>人生オワタ\(^o^)/

この更新自体が、自作はてダラのテストだったりするんですよねー、ねー。