« PHPでBasic認証のパスワードを作ってみよう | トップページ | MySQLの暗号化をやってみよう »

2007年03月11日

住所を都道府県・市区郡・それ以下に分けてみよう

1年程前に「CSVデータをデータベースに一括登録する」をやりました。
その時のお客さんの要望の中に「都道府県」「市区郡」それぞれで検索ができるようにしたいというのがあったのですが、元データが「○○県○○市○○1-2-3」と1つになっていました。
そのままデータベースの中に入れても「都道府県」「市区郡」別に検索することはできそうだったのですが、ほぼ間違いなく動作が重くなるのでデータを分けて登録することにしました。
で、その時に作った関数が以下の通り。
後ほど詳しく書きますがこの関数は完璧ではありません。
また、文字コードはSJISのみです。

/***
* 住所を都道府県 市区郡 以下住所の3つに分ける
* SJIS用
*/
function prefCityAddressSplit($value) {
  $ret = array();
  $search = "^([\x81\x3F-\xFF\xFF]{2,3}[\x93\x73|\x93\xB9|\x95\x7B|\x8C\xA7]{1})"; // 都道府県
  $search .= "([\x81\x3F-\xFF\xFF]+[\x8B\xE6|\x8E\x73|\x8C\x53]{1})"; // 市区郡
  $search .= "([\x81\x3F-\xFF\xFF|0-9a-zA-Z\-]*)"; // それ以下
  if(mb_ereg($search, $value, $string)) {
    $ret['pref'] = $string[1]; // 都道府県
    $ret['city'] = $string[2]; // 市区郡
    $ret['address'] = $string[3];
  }
  if(count($ret) < 3) return $value;
  return $ret;
}

「○○県○○市○○町1-2-3」をprefCityAddressSplit()の中に入れると配列で返してくれます。
住所以外のデータを入れると文字列がそのまま返ってきます。
$address = "○○県○○市○○町1-2-3";
prefCityAddressSplit($address);
array(3) {
  ["pref"]=>
  string(6) "○○県"
  ["city"]=>
  string(6) "○○市"
  ["address"]=>
  string(11) "○○町1-2-3"
}

データの内容が首都圏内だけのデータでしたのでその時は問題なかったのですが、改めて見てみるとバグ発見。。。
「宮崎県都城市○○○1-2-3」で上記の関数を使うと「宮崎県」ではなく「宮崎県都」「城市」「○○○1-2-3」となります^^;
せっかくなので、Blogに掲載することにしたのですが、この問題を発見し格闘すること数時間、まだ解決できません。
うーむ、正規表現は便利だけど難しいなぁ。

トラックバック

このエントリーのトラックバックURL:
http://www.s-memo.net/mt/mt-tb.cgi/35

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)