jpmobileのコードの一部を読んでみた

わけあって、jpmobileの絵文字処理のコードを読んでいます。 そこで、今まで使うことが無かったメソッドが多数使われていたのでRubyのマニュアル を見ながら、irb で少しづつ試して理解ました。

問題のコードは

SJIS_REGEXP = Regexp.union(*SJIS_TO_UNICODE.keys.map{|s| Regexp.compile(Regexp.escape([s].pack('n'),"s"),nil,'s')})
  • まず、[s].pack('n') packは配列の内容を引数で指定された形のデータに変換します(Perl のpack関数から来たものでしょうか)。 n だと ネットワークバイトオーダー(ビッグエンディアン)のunsigned short (16bit 符号なし整数)としてバイト単位で文字(8進数文字)列になります。
>> [0xf7a3].pack('n')
=> "\367\243"
  • Regexp.escape()は正規表現において特別な意味を持つ文字の直前にエ スケープ文字(バックスラッシュ)を挿入してくれます。便利!
>> Regexp.escape('.*')
=> "\\.\\*"
  • Regexp.compile() は第一引数をコンパイルして正規表現オブジェクトを生成します。第二引数でオプション、第三引数は日本語文字コードの指定
  • map は配列などの要素毎にブロックを実行して得られらた値を配列などで返します (Lisper の大好きなメッソド ^^)
  • keys はハッシュのキーを配列として返す
  • Regexp.union() は引数として与えた複数のパターン を | で連結し、Regexp として返します。
  • 引数の先頭に * があると後ろの配列を展開して渡します (実は今まで知らなかった ^^;)。 Ruby らしいですね ^^)
f(*[1,2,3]) は f(1,2,3) と同じ

ということで もし SJIS_TO_UNICODE = {0xF6EF=>0xE516, 0xF6B8=>0xE4DF} なら

>> SJIS_TO_UNICODE  = {0xF6EF=>0xE516,  0xF6B8=>0xE4DF}
=> {63160=>58591, 63215=>58646}
>> SJIS_TO_UNICODE.keys.map{|s| s}
=> [63160, 63215]
>> SJIS_TO_UNICODE.keys.map{|s| Regexp.compile(Regexp.escape([s].pack('n'),"s"),nil,'s')}
=> [/\366\270/s, /\366\357/s]
>> Regexp.union(*SJIS_TO_UNICODE.keys.map{|s| Regexp.compile(Regexp.escape([s].pack('n'),"s"),nil,'s')})
=> /(?-mix:\366\270)|(?-mix:\366\357)/s

ちなみに (?-mix: ....) は ... を実行する際に m, i, x のオプション無しで実行するという意味。

/(?mi-x:\366\270)/  は /\366\270/mi  と同じ