住所の入力はまとめて行える方が便利な場面もありますが、処理によっては都道府県・市区町村をコードに変換して持たせる、あるいは別データとして管理するほうが便利です。とはいえ、変換はなかなか一筋縄では行きません。
辞書式でやる
いちばん単純に考えれば、都道府県・市区町村の全リストを持っておいて、それと照合して切り出すという方法があります。ただ、平成の大合併で1800弱まで減ってはいますが市町村はそれだけの数があって、データを揃える、あるいはフロントエンドで使うにはちょっと大きなデータ量かもしれません。
ということで、全件リストに頼らない方向性を考えていきます。
都道府県を(有無含め)判別
まずは、都道府県を切り出してみましょう。47個しかないのでリスト直持ちでもいいのですが、都道府県のほとんどが「2文字+都道府県のいずれか」で、3文字のものが神奈川県・和歌山県・鹿児島県だけなので、正規表現ですんなり切り出せそうです(「2文字または3文字+都道府県」としてしまうと、「東京都府/中市」や「宮崎県都/城市」を切り誤ることがあります)。
ただ、1つ気を付けないといけないのは、(実在するかどうかよくわかりませんが)「○市都町」のように都道府県なしで書いてあった場合に、「○市都」が都道府県だと誤認されてしまうことです。幸い、「市区町村」の文字を含む都道府県は現状ないので、/^([^市区町村]{2}[都道府県]|[^市区町村]{3}県)/
とすれば、都道府県がある場合にそれを抽出する正規表現となります。
市区町村の切りだし
(あったとしたら)都道府県を抽出した上で、次は市区町村を切り出して行きましょう。いちばんシンプルなアルゴリズムを考えると、「2文字目以降で初めに現れる「市区町村」のどれかで切る」という方法が考えられます。大半の市区町村はこれでうまく行くのですが、「東京都武蔵村/山市」など、これでいかないパターンもいくつかあります。とはいえ、パターンは少ないのでこっちで網羅できればきちんと切れます。
そのような、途中に「市町村」の文字が入る市町村名・郡名は以下のようになっています(町村名については、郡名付きになると途中になるので、先頭のものも入れてあります)。2015年9月現在です。
- 北海道余市郡仁木町・赤井川村・余市町
- 宮城県柴田郡村田町
- 山形県
- 東村山郡山辺町・中山町
- 西村山郡河北町・西川町・朝日町・大江町
- 北村山郡大石田町
- 福島県
- 田村市
- 田村郡三春町・小野町
- 栃木県芳賀郡市貝町
- 群馬県佐波郡玉村町
- 東京都武蔵村山市・東村山市・羽村市
- 新潟県十日町市
- 富山県中新川郡上市町
- 石川県野々市市
- 山梨県西八代郡市川三郷町
- 長野県大町市
- 三重県四日市市
- 兵庫県神崎郡市川町
- 奈良県高市郡高取町・明日香村
- 奈良県吉野郡下市町
- 広島県廿日市市
- 佐賀県杵島郡大町町
- 長崎県大村市
これらにヒットするように正規表現へまとめると、以下のようになります(読みやすいように途中改行しています)。
/^(余市郡(仁木町|赤井川村|余市町)|余市町|柴田郡村田町|(武蔵|東)村山市|
[東西北]村山郡...?町|田村(市|郡..町)芳賀郡市貝町|(佐波郡)?玉村町|[羽大]村市|
(十日|大)町市|(中新川郡)?上市町|(野々|[四廿]日)市市|
西八代郡市川三郷町|神崎郡市川町|高市郡(高取町|明日香村)|(吉野郡)?下市町|
(杵島郡)?大町町)/
ヒットしなければ、あとは市区町村で切るだけです。
その他
これは、以前個人ブログへ掲載したものを、少し改良の上再掲載しています。