住所の分割 都道府県/市区町村/町名

住所を正規表現で都道府県、市区町村、町名に分割

PHP

preg_match('/(東京都|北海道|(?:京都|大阪)府|.{6,9}県)((?:四日市|廿日市|野々市|臼杵|かすみがうら|つくばみらい|いちき串木野)市|(?:杵島郡大町|余市郡余市|高市郡高取)町|.{3,12}市.{3,12}区|.{3,9}区|.{3,15}市(?=.*市)|.{3,15}市|.{6,27}町(?=.*町)|.{6,27}町|.{9,24}村(?=.*村)|.{9,24}村)(.*)/', $str, $matches);

UTF8

文字コードがUTF8のため.{2,3}県ではなく、.{6,9}県。

連続した文字列の対応

○○市△△市、○○町△△町などの連続して同じ文字列が含まれるものを先読み(.{3,15}市(?=.*市))で抽出。2回目の同じ文字列が終端にならないようにする。
これにマッチしない四日市市、廿日市市、野々市市、杵島郡大町町を先行処理。

Array ( [0] => 千葉県市川市市川 [1] => 千葉県 [2] => 市川市 [3] => 市川 ) Array ( [0] => 三重県四日市市相生町 [1] => 三重県 [2] => 四日市市 [3] => 相生町 )

政令指定都市以外の○○市△△区

臼杵を○○市△△区より先行処理。
この組み合わせが他にも多数あるのであれば、.{3,12}市.{3,12}区を(?:札幌|仙台|さいたま|千葉|横浜|川崎|相模原|新潟|静岡|浜松|名古屋|京都|大阪|堺|神戸|岡山|広島|北九州|福岡|熊本)市.{3,12}区にすべき。

Array ( [0] => 大分県臼杵市市浜千代田区 [1] => 大分県 [2] => 臼杵市 [3] => 市浜千代田区 )

文字数範囲指定

町名に市・区・町・村が含まれているものがあるため、市・区・町・村に文字数制限(.{3,12}市.{3,12}区)を設定し、これを回避する。
市については、{3,18}市にすると、町名に含まれる市まで抽出してしまうので、{3,15}市に設定し、かすみがうら、つくばみらい、いちき串木野を先行処理。
(参考)
区(市部分):さいたま市(4字)-堺市(1字)
区(区部分):保土ヶ谷区(4字)-堺区(1字)
23区:江戸川区(3字)-港区(1字)
市:かすみがうら市(6字)、南アルプス市(5字)-津市(1字)
町:南都留郡富士河口湖町(9字)-大島町(2字)
村:北秋田郡上小阿仁村(8字)-新島村(2字)

Array ( [0] => 茨城県かすみがうら市有河 [1] => 茨城県 [2] => かすみがうら市 [3] => 有河 )

市が含まれる町

町より市を先に処理しているため、市が含まれる余市郡余市町、高市郡高取町を市より先に処理。

Array ( [0] => 北海道余市郡余市町朝日町 [1] => 北海道 [2] => 余市郡余市町 [3] => 朝日町 )

12万件の住所一覧で試したのですが、ほぼ分割できているのではないかと思います。もし、うまく分割できないところが見つかれば更新する予定です。

最新の記事

プロフィール

流されるままにウェブ業界で仕事しています。主にLAPP環境でPHPを書いています。最近はjQueryで遊んでいます。
※動作確認について