Ruby19 異体字の変換

仕事で,大量の人名リストから対象の人物のID(システムログイン用のID)を調査する必要があったのだが,IDと紐付いている人名データと,大量の人名リストは作成した部署が違うせいもあって,異体字などで使われている文字が微妙に違う場合がある.
そのままでは検索で見付からないので,苦肉の策として,文字列に含まれる異体字を一番簡単な(代表的な)文字に変換したうえで比較するというちょっと乱暴な方法を使うことにした.
そこで String クラスに,文字列中の異体字が存在する文字を一番簡単な文字に変換するメソッド itaiji_normalize を書いてみた.あと,ついでに,複数の異体字のバリエーションを全て配列で返す itaiji_probable も書いてみた.

#!/usr/bin/env ruby19
# coding: utf-8

ITAIJI_LIST="/hogehoge/itaiji-list.txt"

=begin
get_itaiji-list.sh で取得したファイル itaiji-list.txt を読み込み
String クラスに String.itaiji_normalize メソッドを追加する

使用例
p "学學斈".itaiji_normalize => "学学学"

=end

class String
  @@itaiji_normalize_list = nil

  def itaiji_setup
    @@itaiji_normalize_list = Array.new
    File.open(ITAIJI_LIST){|fd|
      fd.each{|l|
        l = l.encode("utf-8", "windows-31j").chomp
        next unless /<b>/.match(l)
        l = l.gsub(/(<\/?b>|\|| |[|]|\[|\])/, '')
        itaiji_dst = l[0]
        itaiji_src = "(" + l[1..-1].split('').join("|") + ")"
        @@itaiji_normalize_list << [Regexp.new(itaiji_src), itaiji_dst]
      }
    }
#    p @@itaiji_normalize_list
  end
  protected :itaiji_setup

  def itaiji_probable
    itaiji_setup if @@itaiji_normalize_list == nil
 
    pa = [self]                 # probable array
    @@itaiji_normalize_list.each{|src_regexp,dst|
      next unless src_regexp.match(pa[0])
      pa += pa.map{|str|   # append converted string into array
        str.gsub(src_regexp,dst)
      }
    }
    return pa
  end

  def itaiji_normalize
    itaiji_setup if @@itaiji_normalize_list == nil

    @@itaiji_normalize_list.each{|src_regexp,dst|
      self.gsub!(src_regexp, dst)
    }
    self
  end
end

=begin
# test code テストコード
p "学學斈" => "学學斈"
p "学學斈".itaiji_normalize => "学学学"
=end

ちなみに,このファイルから読み込んでいる異体字リスト(ITAIJI_LIST)を格納しているファイルは,ネットで見付けたこのページ(http://www.h5.dion.ne.jp/~wing-x/ezhtml/ita/lst10-01.html)のデータを下記のようにして使わせてもらっている.

fetch -o - \
 http://www.h5.dion.ne.jp/~wing-x/ezhtml/ita/lst10-01.html \
 http://www.h5.dion.ne.jp/~wing-x/ezhtml/ita/lst10-02.html \
 http://www.h5.dion.ne.jp/~wing-x/ezhtml/ita/lst10-03.html \
 http://www.h5.dion.ne.jp/~wing-x/ezhtml/ita/lst10-04.html \
 http://www.h5.dion.ne.jp/~wing-x/ezhtml/ita/lst10-05.html \
 > itaiji-list.txt