住所データを整形する
目次
はじめに
地図を加工するときに2種類の住所データを比較してプロットしたいことがよくある
例えば、丁町目ポリゴンデータとデータを測定した際の住所を重ね合わせる場合、世間的には11桁コードというデータ(要するに住所を数字化した物)で突合させるらしい。しかし、費用がかかるので出来るだけ安く突合できないか考えてみた
住所合わせ
よく問題になるのが住所の不整合。典型的な例では以下のような場合
福島県郡山市田村町桜ケ丘1丁目
福島県郡山市田村町桜ケ丘一丁目
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!@#アイウガダパ
これで、半角を全角にすることが出来ます