住所データを整形する

提供: dococo wiki
2016年8月13日 (土) 11:37時点におけるimported>Webmasterによる版 (ページの作成:「== はじめに == 地図を加工するときに2種類の住所データを比較してプロットしたいことがよくある<br /> 例えば、丁町目ポリゴ...」)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
ナビゲーションに移動 検索に移動

はじめに

地図を加工するときに2種類の住所データを比較してプロットしたいことがよくある
例えば、丁町目ポリゴンデータとデータを測定した際の住所を重ね合わせる場合、世間的には11桁コードというデータ(要するに住所を数字化した物)で突合させるらしい。しかし、費用がかかるので出来るだけ安く突合できないか考えてみた

住所合わせ

よく問題になるのが住所の不整合。典型的な例では以下のような場合

  1. 福島県郡山市田村町桜ケ丘1丁目
  2. 福島県郡山市田村町桜ケ丘一丁目


use strict;
use warnings;
use utf8;

#これで標準出力が自動的にcp932にencodeされる
binmode STDOUT , ":encoding(cp932)";

{
  use Encode;
  use Encode::JP::H2Z;
  my $eucjp = Encode::find_encoding('eucjp');
  sub hankaku2zenkaku { 
    my $str = $eucjp->encode(shift);
    Encode::JP::H2Z::h2z(\$str);
    $eucjp->decode($str);
  }
  sub zenkaku2hankaku { 
      my $str = $eucjp->encode(shift);
      Encode::JP::H2Z::z2h(\$str);
      $eucjp->decode($str);
  }
}

print hankaku2zenkaku("オンドゥルルラギッタンディスカー!?"), "\n";
print zenkaku2hankaku("ウソダドンドコドーン"), "\n";

文字コードを意識的にプログラムする

入り口で decode して、内部ではすべて flagged utf8 で扱い、出口で encode する。これがすべてです!とにかくこの基本方針をまもっていれば幸せになれます。

という言いつけを守るために、binmodeを使わないで意識的に文字コードを考えたら私的には以下のようにするのが良いと感じました。
このようにすることで、出力する直前に必要な文字コードに変換して出力するという意識になります。


use strict;
use warnings;
use utf8;

{
  use Encode;
  use Encode::JP::H2Z;
  my $eucjp = Encode::find_encoding('eucjp');
  sub hankaku2zenkaku { 
    my $str = $eucjp->encode(shift);
    Encode::JP::H2Z::h2z(\$str);
    $eucjp->decode($str);
  }
  sub zenkaku2hankaku { 
      my $str = $eucjp->encode(shift);
      Encode::JP::H2Z::z2h(\$str);
      $eucjp->decode($str);
  }
}

print encode('cp932',hankaku2zenkaku("オンドゥルルラギッタンディスカー!?")), "\n";
print encode('cp932',zenkaku2hankaku("ウソダドンドコドーン")), "\n";

文字も記号も数字も全て半角を全角にする

いろいろ使って見て分かったことですけど、半角を全角にする場合にはモジュールという便利な物を使う必要がある
モジュールには標準モジュールのEncode.pmと別途インストールして使用するUnicode::JapaneseおよびLingua::JA::Regular::Unicodeがある。
ここでやりたいこととと異なってきた内容で、標準モジュールのEncode.pm要するに今まで説明した

      Encode::JP::H2Z::z2h(\$str);

といった、Encode::JP::H2Z::z2hでは全角変換はカナのみで、数字や記号については変換しない事が分かりました。
これを回避するために新たにuse Unicode::Japanese;を使うと数字や記号も変換しますUnicode::Japanese;を使う場合にはUnicode::Japaneseをインストールしなければなりません。

Unicode::Japaneseインストール方法

$ perl -MCPAN -e shell
cpan> install Unicode::Japanese

インストール環境に問題が無ければこれでモジュールがインストールされます。

サンプルプログラム

これもUTF-8で保存する必要がありますので注意が必要です

#UTF-8で保存する
use strict;
use warnings;
use utf8;
use Encode;#これがないと「Undefined subroutine &main::encode called at」が出る
use Unicode::Japanese;

#$str_hに半角データを入れる
my $str_h = '012ABCabc!@#アイウガダパ';

#cp932で表示してみる(1)
print encode('cp932',$str_h),"\n";

#Unicode::Japaneseで表示してみる(2)cp932でもsjisでも表示される
print Unicode::Japanese->new($str_h)->cp932,"\n";

#(1)と(2)は同じ結果になる、表示ルールを変えただけ

#h2z(半角から全角)
#通常の表示方法
#->cp932を->getとするとutf8で保存される
print Unicode::Japanese->new($str_h)->h2z->cp932,"\n";

これを実行した場合以下の結果になります
012ABCabc!@#アイウガダパ
012ABCabc!@#アイウガダパ
これで、半角を全角にすることが出来ます