ruby で企業名の名寄せ
業務で企業の情報を整理している。
大した内容ではないが、タウンページの情報と、別の企業リストの情報の統合であるが、ここで、様々な文字処理に関する技術を習得した。
これを少し整理しておこう。
文字コード
データの取得はSJISで、結果はEXCEL。内部はUTFに統一したい。(まだ完全ではないが)
IO.readlines(filename, encoding:"Shift_JIS:UTF-8") File.open(filename,"w:Shift_JIS:UTF-8")
これで外部と内部をきれいに分けられる。
SJISとCP932
これまで、日本語コードは、SJISとUTF8とEUCを使っていたが、
漢字の処理をしていて、異体字(「崎」に対する「﨑」等)で、エラーがでて
困っていた。﨑を崎に変えて処理する等。
﨑の入っているファイルのコードをnkf -g で見ると、CP932となっている。
今まで気にしていなかったが、調べてみると、CP932(別名Windows31)は、SJISを拡張したもので、
立派に規格化されて、上のコード変換でも使える。
weblabo.oscasierra.net
いままで、viでも、fileencodingsに、CP932を入れていなかったため、文字化けしていたが、これを入れると何でもない。Shift_JISよりも、CP932の方が、便利。
エラーが出たとき、ちゃんと原因分析して対処しないといけませんね。
半角と全角の変換
しばしば"(株)"のような記号交じりのものがある。住所や番号も、半角だったり全角だったり。これは、全角に統一しておくと、処理しやすい。
英数半角文字を全角にするライブラリは、標準には無いようだ。
class String #Convert #convert ascii <-> utf,ascii <-> sjis $tr_a2u=[" !-}~","\u3000\uFF01-\uFF5D\uFF5E"] def asc2utf;self.tr(*$tr_a2u);end def utf2asc;self.tr(*($tr_a2u.reverse));end end #class
これで、trを使ってスペースからチルダまでを変換できる。
半角カナ文字の全角変換
全角かな文字は、濁音、半濁音が1文字で表記されるが、
半角カナ文字は、濁点、半濁点が、別文字である。
このため、①半角を全角にする際、「が」を「カ」と「゙」にすること、
②コード表の並びがことなることから、かなり面倒になる。
とりあえず、②の対応のみとして、以下のメソッドを作成した。
def sub_pairs(pairs) #substitute pairs of strings of from & to pairs.inject(self){|ans,(frm,to)| ans.sub(frm,to)} end # KANA 半角と全角順番異なる # 課題 全角濁音(1文字)を半角(2文字)に変換への対応 k1u=("\uFF61".."\uff9f").to_a*"" #("。".."゚") #半角カナ k2u=%w[ 12290 12300 12301 12289 12539 12530 12449 12451 12453 12455 12457 12515 12517 12519 12483 12540 12450 12452 12454 12456 12458 12459 12461 12463 12465 12467 12469 12471 12473 12475 12477 12479 12481 12484 12486 12488 12490 12491 12492 12493 12494 12495 12498 12501 12504 12507 12510 12511 12512 12513 12514 12516 12518 12520 12521 12522 12523 12524 12525 12527 12531 12443 12444 ].map{|i| i.to_i.chr("UTF-8")}*"" #全角カナ $tr_a2uk=[k1u,k2u]; def asc2utfk;self.tr(*$tr_a2uk);end def utf2asck;self.tr(*($tr_a2uk.reverse));end
ひらがなとカタカナ
半角は、カタカナしか無いため、ひらがなを半角カナで圧縮するデータもある。
この場合、カタカナをひらがなに変換する。
$hk=("\u3041".."\u3096").to_a #Hiragana UTF $kk=("\u30A1".."\u30F6").to_a #katakana UTF def hk2kk;ans=self;ans.tr(hk,kk);end #HiraK->KataK UTF def kk2hk;ans=self;ans.tr(kk,hk);end #KataK->HiraK UTF
略称の展開
「株式会社」と書いたり、「(株)」と書いたり。
略称も様々である。これらのデータをテキストにして、置換テーブルを作成してsub_pairsで長い方に統一した。