郵便番号から住所が補完される入力フォームを作るときに考えること

この記事は、[Wano Group Advent Calendar 2024](https://qiita.com/advent-calendar/2024/wano-group)の~~3日目~~7日目の記事です。（3日に間に合わず、移動させていただきました。すみません...。）

住所をシステムで扱う際のつらいポイントがあるという話は定期的に話題になっていたりもするので、ご存じの方も多いかもしれません。ただ、大事な話は何度してもいいだろうということで、まだ知らない方のためにも書いていこうと思います。

また、これらの大体のことは、住所データや郵便番号検索用のAPIを提供されている[ケンオールさんのブログ](https://blog.kenall.jp/)に書いてあります。詳細を知りたい方はケンオールさんのブログも参照していただければと思います。

色々記載していますが、結論を知りたい方は[結局どうすればいいか](#結局どうすればいいか)をご覧ください。

## 特殊な郵便番号・町域名を持つ住所

郵便番号を入力すると都道府県・市区町村・町域まで自動補完してくれるUIを提供しているサービスは多く存在し、皆さんにも馴染みがあると思います。しかし、このUIを実装するにあたって、いくつか特殊なケースを考慮する必要があります。

### 1. 1つの郵便番号に複数の住所が紐づく場合

まず、前提として、郵便番号と町域の関係は`1:1`ではありません。以下のように、1つの郵便番号に対して、複数の町域が紐づく場合が存在します。
2024年12月現在では、郵便番号の数では24件、町域のレコード数で換算すると776件存在するようです。

例）

| 郵便番号                                                                     | 都道府県 | 市区町村 | 紐づく件数 |
| ---------------------------------------------------------------------------- | -------- | -------- | ---------- |
| [〒452-0961](https://www.post.japanpost.jp/cgi-zip/zipcode.php?zip=452-0961) | 愛知県   | 清須市   | 66件       |
| [〒779-3405](https://www.post.japanpost.jp/cgi-zip/zipcode.php?zip=779-3405) | 徳島県   | 吉野川市 | 44件       |

そのため、郵便番号が7桁入力されても対応する住所が確定しないケースも考慮した入力フォームである必要があります。

#### 1-1. 市区町村を跨ぐ場合

上記の多くは都道府県・市区町村は同一で複数の異なる町域に紐づいているケースですが、稀に市区町村を跨いで同じ郵便番号が割り当てられているケースも存在します。

例）

| 郵便番号                                                                     | 都道府県 | 市区町村     | 町域                 |
| ---------------------------------------------------------------------------- | -------- | ------------ | -------------------- |
| [〒700-0941](https://www.post.japanpost.jp/cgi-zip/zipcode.php?zip=7000941)  | 岡山県   | 岡山市南区   | 青江                 |
| （同上）                                                                     | 岡山県   | 岡山市北区   | 青江                 |
| [〒950-0000](https://www.post.japanpost.jp/cgi-zip/zipcode.php?zip=950-0000) | 新潟県   | 新潟市北区   | 以下に掲載がない場合 |
| （同上）                                                                     | 新潟県   | 新潟市江南区 | 以下に掲載がない場合 |
| （同上）                                                                     | 新潟県   | 新潟市中央   | 以下に掲載がない場合 |
| （同上）                                                                     | 新潟県   | 新潟市西蒲区 | 以下に掲載がない場合 |
| （同上）                                                                     | 新潟県   | 新潟市西区   | 以下に掲載がない場合 |
| （同上）                                                                     | 新潟県   | 新潟市東区   | 以下に掲載がない場合 |

〒950-0000の新潟県新潟市のケースは後述する[2-1](#2-1-該当する住所がなく下2桁が-00-の郵便番号が割り当てられている場合)のケースにも該当しています。

また、以前は〒432-8053（[静岡県浜松市中区](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=22&city=1221311&addr=%E6%B5%9C%E6%9D%BE)、[静岡県浜松市南区](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=22&city=1221341&addr=%E6%B5%9C%E6%9D%BE)）もこのケースに該当していたようなのですが、2024年1月より[浜松市中央区へと変更](https://www.post.japanpost.jp/zipcode/merge/index.html)され、該当しなくなりました。

#### 1-2. 都道府県を跨ぐ場合

市区町村だけでなく、複数の都道府県を跨ぐ場合も存在します。2024年12月現在では郵便番号の数としては3件存在します。

| 郵便番号                                                                     | 都道府県 | 市区町村       | 町域                 |
| ---------------------------------------------------------------------------- | -------- | -------------- | -------------------- |
| [〒498-0000](https://www.post.japanpost.jp/cgi-zip/zipcode.php?zip=6180000)  | 三重県   | 桑名郡木曽岬町 | 以下に掲載がない場合 |
| （同上）                                                                     | 愛知県   | 弥富市         | 以下に掲載がない場合 |
| [〒618-0000](https://www.post.japanpost.jp/cgi-zip/zipcode.php?zip=6180000)  | 京都府   | 乙訓郡大山崎町 | 以下に掲載がない場合 |
| （同上）                                                                     | 大阪府   | 三島郡島本町   | 以下に掲載がない場合 |
| [〒871-0000](https://www.post.japanpost.jp/cgi-zip/zipcode.php?zip=871-0000) | 大分県   | 中津市         | 以下に掲載がない場合 |
| （同上）                                                                     | 福岡県   | 築上郡吉富町   | 以下に掲載がない場合 |

また、これらはいずれも後述する[2-1](#2-1-該当する住所がなく下2桁が-00-の郵便番号が割り当てられている場合)のケースにも該当しています。

### 2. 1つの町域が複数の郵便番号が紐づく場合

逆に、1つの町域に対して、複数の郵便番号が紐づく場合もあります。このように、郵便番号と町域の関係は実態としては`n:n`になっているようです。

#### 2-1. 該当する住所がなく、下2桁が `00` の郵便番号が割り当てられている場合

こちらに該当する町域は2024年12月現在で1870件存在します。
新規で追加されたり、変更された場合等、相当する郵便番号が存在しない地域に割り当てられるようです。\
この郵便番号に該当する町域はすべて「以下に掲載がない場合」という名称になっており、住所を指定する人に情報を補完してもらう前提のもののようです。

> 9）の項目位置に、「"以下に掲載がない場合"」とは、お探しの町域が見つからない場合にお書きいただく番号であり、町域を特定するものではありませんのでご注意ください。

引用元： [郵便番号データの説明 - 日本郵便](https://www.post.japanpost.jp/zipcode/dl/readme.html)

例）

| 郵便番号                                                                                              | 都道府県 | 市区町村       | 町域                 |
| ----------------------------------------------------------------------------------------------------- | -------- | -------------- | -------------------- |
| [〒399-0400](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=20&city=1203820&id=76076&merge=)  | 長野県   | 上伊那郡辰野町 | 以下に掲載がない場合 |
| [〒665-0000](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=28&city=1282140&id=114248&merge=) | 兵庫県   | 宝塚市         | 以下に掲載がない場合 |

ちなみに、郵便局のページでは、[バーコードに必要な文字情報の抜き出し法(2/9)](https://www.post.japanpost.jp/zipcode/zipmanual/p18.html)に「代表の郵便番号」というワードで少し言及されているのですが、少し調べた限り公式的な概念として言及されているソースを見つけることはできませんでした。運用上のルールとして定着しているくらいの感じなのでしょうか。\
（2024年12月現在では、下2桁が`00`なことと町域名が「以下に掲載がない場合」となることは同値の関係のようです）

##### 2-1-1. 地名として「以下」が町域に含まれる場合

上記とは別に、実際に「以下」という地名を持つ住所が存在します。

[〒851-0502 長崎県長崎市以下宿町](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=42&city=1422010&id=148962&merge=)

また、後述の[2-5](#2-5-その他で但し書きがされている場合)に該当する`（）`の但し書きの中で「以下」が含まれているケースもあります。

[〒649-6413 和歌山県紀の川市竹房（４５０番地以下）](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=30&city=1302080&id=121465&merge=)

そのため、町域名を直接置換する場合、「以下に」等でヒットさせた上でマッチした町域名を削除する必要があります。

#### 2-2. ある地域全体を表す「一円」が町域に含まれる場合

ある地域全体を表す意味で、「〇〇一円」という町域が割り当てられている住所がいくつか存在します。この場合、該当する町域名がないものとして扱われています。
村や町にあたる地域全体を表すのに使われることが多く、2024年12月現在ではこちらに該当する町域が22件存在するようです。

> 9）の項目位置に、「"○○市（または町・村）一円"」とは、町域名がない市区町村の場合にお書きいただく番号です。

引用元： [郵便番号データの説明 - 日本郵便](https://www.post.japanpost.jp/zipcode/dl/readme.html)

| 郵便番号                                                                                              | 都道府県 | 市区町村         | 町域         |
| ----------------------------------------------------------------------------------------------------- | -------- | ---------------- | ------------ |
| [〒100-0301](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=13&city=1133620&id=50531&merge=)  | 東京都   | 利島村           | 利島村一円   |
| [〒100-0601](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=13&city=1133640&id=50536&merge=)  | 東京都   | 神津島村         | 神津島村一円 |
| [〒100-1301](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=13&city=1133820&id=50544&merge=)  | 東京都   | 御蔵島村         | 御蔵島村一円 |
| [〒100-1701](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=13&city=1134020&id=50551&merge=)  | 東京都   | 青ヶ島村         | 青ヶ島村一円 |
| [〒958-0061](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=15&city=1155860&id=61862&merge=)  | 新潟県   | 岩船郡粟島浦村   | 粟島浦村一円 |
| [〒401-0320](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=19&city=1194290&id=74360&merge=)  | 山梨県   | 南都留郡鳴沢村   | 鳴沢村一円   |
| [〒384-1211](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=20&city=1203060&id=75909&merge=)  | 長野県   | 南佐久郡南相木村 | 南相木村一円 |
| [〒384-1201](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=20&city=1203070&id=75910&merge=)  | 長野県   | 南佐久郡北相木村 | 北相木村一円 |
| [〒399-4511](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=20&city=1203850&id=76100&merge=)  | 長野県   | 上伊那郡南箕輪村 | 南箕輪村一円 |
| [〒399-4301](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=20&city=1203880&id=76106&merge=)  | 長野県   | 上伊那郡宮田村   | 宮田村一円   |
| [〒395-0601](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=20&city=1204090&id=76138&merge=)  | 長野県   | 下伊那郡平谷村   | 平谷村一円   |
| [〒395-0701](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=20&city=1204100&id=76139&merge=)  | 長野県   | 下伊那郡根羽村   | 根羽村一円   |
| [〒399-1601](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=20&city=1204120&id=76143&merge=)  | 長野県   | 下伊那郡売木村   | 売木村一円   |
| [〒399-1801](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=20&city=1204140&id=76148&merge=)  | 長野県   | 下伊那郡泰阜村   | 泰阜村一円   |
| [〒397-0201](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=20&city=1204290&id=76183&merge=)  | 長野県   | 木曽郡王滝村     | 王滝村一円   |
| [〒390-1301](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=20&city=1204500&id=76210&merge=)  | 長野県   | 東筑摩郡山形村   | 山形村一円   |
| [〒399-8501](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=20&city=1204820&id=76235&merge=)  | 長野県   | 北安曇郡松川村   | 松川村一円   |
| [〒717-0201](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=33&city=1335860&id=129529&merge=) | 岡山県   | 真庭郡新庄村     | 新庄村一円   |
| [〒761-3110](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=37&city=1373640&id=138518&merge=) | 香川県   | 香川郡直島町     | 直島町一円   |
| [〒781-6410](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=39&city=1393030&id=142582&merge=) | 高知県   | 安芸郡田野町     | 田野町一円   |
| [〒872-1501](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=44&city=1443220&id=157010&merge=) | 大分県   | 東国東郡姫島村   | 姫島村一円   |
| [〒901-3601](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=47&city=1473560&id=161055&merge=) | 沖縄県   | 島尻郡渡名喜村   | 渡名喜村一円 |

##### 2-2-1. 地名として「一円」が町域に含まれる場合

上記では「一円」が「ある地域全体」の意味で使用されていましたが、それとは別に実際に「一円」という地名を持つ住所も存在します。

[〒522-0317 滋賀県犬上郡多賀町一円](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=25&city=1254430&id=99891&merge=)

そのため、町域名を置換する場合、一円の前に何らかの単語を含む（`.+一円`）ときにのみ町域名を削除する必要があります。

#### 2-3. 「○○の次に××がくる場合」

町域名がなく、市区町村の後にそのまま番地が続く場合に町域名として「○○の次に××がくる場合」が設定されている場合もあるようです。2024年12月時点では21件が該当しています。

> 市区町村名の後ろに町域名がなく、番地がくる住所（例：○○郡△△町1234番地）の場合にお書きいただく番号です。

引用元： [郵便番号データの説明 - 日本郵便](https://www.post.japanpost.jp/zipcode/dl/readme.html)

こちらの場合も、「の次に」を含む場合は町域名が削除されているのが望ましいでしょう。

| 郵便番号   | 都道府県 | 市区町村       | 町域                                         |
| ---------- | -------- | -------------- | -------------------------------------------- |
| 〒306-0433 | 茨城県   | 猿島郡境町     | 境町の次に番地がくる場合                     |
| 〒409-0142 | 山梨県   | 北都留郡小菅村 | 小菅村の次に１〜６６３番地がくる場合         |
| 〒409-0211 | 山梨県   | 北都留郡小菅村 | 小菅村の次に６６４番地以降がくる場合         |
| 〒394-0091 | 長野県   | 岡谷市         | 岡谷市の次に番地がくる場合                   |
| 〒399-7201 | 長野県   | 東筑摩郡生坂村 | 生坂村の次に番地がくる場合                   |
| 〒501-3701 | 岐阜県   | 美濃市         | 美濃市の次に番地がくる場合                   |
| 〒503-2121 | 岐阜県   | 不破郡垂井町   | 垂井町の次に番地がくる場合                   |
| 〒415-0001 | 静岡県   | 下田市         | 下田市の次に番地がくる場合                   |
| 〒669-1536 | 兵庫県   | 三田市         | 三田市の次に番地がくる場合                   |
| 〒649-2211 | 和歌山県 | 西牟婁郡白浜町 | 白浜町の次に番地がくる場合                   |
| 〒731-4301 | 広島県   | 安芸郡坂町     | 坂町の次に番地がくる場合                     |
| 〒769-0210 | 香川県   | 綾歌郡宇多津町 | 宇多津町の次に番地がくる場合                 |
| 〒766-0002 | 香川県   | 仲多度郡琴平町 | 琴平町の次に１〜４２６番地がくる場合（川東） |
| 〒766-0001 | 香川県   | 仲多度郡琴平町 | 琴平町の次に４２７番地以降がくる場合（川西） |
| 〒796-0088 | 愛媛県   | 八幡浜市       | 八幡浜市の次に番地がくる場合                 |
| 〒781-2110 | 高知県   | 吾川郡いの町   | いの町の次に番地がくる場合                   |
| 〒811-3213 | 福岡県   | 福津市         | 福津市の次に番地がくる場合                   |
| 〒855-0038 | 長崎県   | 島原市         | 島原市の次に番地がくる場合                   |
| 〒857-2427 | 長崎県   | 西海市         | 大島町の次に番地がくる場合                   |
| 〒871-0099 | 大分県   | 中津市         | 中津市の次に番地がくる場1合                  |
| 〒879-1506 | 大分県   | 速見郡日出町   | 日出町の次に番地がくる場合                   |

#### 2-4. 町域が`、`で区切られる場合

①複数の町域が1つの郵便番号にまとまっている場合や、②ある町域の中で特定の番地だけは別の郵便番号が割り当てられているような場合、「、」で区切って町域・番地を表すケースがあります。2024年12月現在ではそれぞれ、

- ① - 14件
- ② - 557件

存在します。

例）①のケース

| 郵便番号                                                                                             | 都道府県 | 市区町村       | 町域                       |
| ---------------------------------------------------------------------------------------------------- | -------- | -------------- | -------------------------- |
| [〒029-5505](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=3&city=1033660&id=14615&merge=)  | 岩手県   | 和賀郡西和賀町 | 湯本２９地割、湯本３０地割 |
| [〒440-0833](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=23&city=1232010&id=87114&merge=) | 愛知県   | 豊橋市         | 飯村町西山、高山           |

①のケースに関しては、親切にする場合は、`、`で分割して別のレコードとして扱い、ユーザーに選択させる形にすることもできるでしょう。

例）②のケース

| 郵便番号                                                                                              | 都道府県 | 市区町村     | 町域                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ----------------------------------------------------------------------------------------------------- | -------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [〒602-8368](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=3&city=1033660&id=14615&merge=)   | 京都府   | 京都市上京区 | 北町（上の下立売通天神道西入上る、上の下立売通御前西入、上の下立売通御前西入上る、上の下立売通御前西入２丁目、上の下立売通御前西入２筋目、下長者町通御前西入、天神道上の下立売上る、天神道仁和寺街道下る、天神道下立売上る、天神道妙心寺道上る、天神道妙心寺道上る西入、仁和寺街道天神道西入下る、仁和寺街道天神道東入下る、御前通上の下立売上る、御前通上の下立売上る西入、御前通下立売上る、御前通下長者町上る西入、御前通仁和寺街道下る西入、御前通妙心寺道上る西入、御前通西裏上の下立売上る、御前通西裏下立売上る）                                                                |
| [〒891-1275](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=46&city=1462010&id=158074&merge=) | 鹿児島県 | 鹿児島市     | 川上町（３６４９、３６６１、３６６７、３６６７−３、３６６９−４、３６７１、３６７２、３６７３−１、３６７４、３６７４−２、３６７４−８、３６８０−１、３７０１、３７０４、３７２３−３、３７２３−５、４１２５、４１２８、４１２８−３、４１２８−４、４１２８−５、４１３２、４１３２−４、４１３３、４１３３−２、４１３８、４２０３、４２０３−１、４２０９、４２０９−６、４２１１−１、４２１５、４２１５−１、４２１６−３、４２１６−１０、４２１６−１２、４２３６−１、４２３８、４２３８−１、４２３８−２、４２４１、４２４２、４２４２−３、４２４４、４２４４−１、４２４４−３、４２４４−４番地） |
| [〒921-8046](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=17&city=1172010&id=66222&merge=)  | 石川県   | 金沢市       | 大桑町（ア、イ、ヰ、ウ、上野、ヲ、オ乙、鐘搗山、上川原、上猫下、ク、ケ、御所谷、小寺山、シ、下上野、下西欠、平、チ、ツ乙、ツ丙、テ、ト、中上野、中尾山、中平、中ノ大平、西ノ山、猫シタイ、ノ、ハ、開、法師山、坊山、マ、鱒川淵、ム、元末、元涌波庚、ヤ、リ、ル、レ乙、レ甲、ロ乙、ロ甲、和）                                                                                                                                                                                                                                                                                            |

どれも見た目にもインパクトのある住所です。この②のケースは[2-5](#2-5-その他で但し書きがされている場合)のように`（）`で補足されているパターンでもあるので、詳細は後述します。

また、3つ目の[〒921-0846](https://www.post.japanpost.jp/cgi-zip/zipcode.php?zip=921-8046)は[石川県金沢市三小牛町（ヘ）](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=17&city=1172010&id=66643&merge=)にも紐づいています。\
つまり、前述の[1](#1-1つの郵便番号に複数の住所が紐づく場合)のパターンにも当てはまるケースです。テストデータとして有用かもしれません。

#### 2-5. その他`（）`で但し書きがされている場合

他にも町域名に`（）`で補足情報が記載されていパターンがいくつも存在します。

[2-1](#2-1-該当する住所がなく下2桁が-00-の郵便番号が割り当てられている場合)や[2-2](#2-2-ある地域全体を表す一円が町域に含まれる場合)のケースと同様、あくまで町域を特定するためのものではないため、これらの補足情報は削除された状態になっているのが望ましいと思われます。（そのまま扱うとデータ長が大きくなりすぎるという実際的な問題もあります）

- `（）`で一つの地名が補足される場合
  - 例
    - [〒891-4401 鹿児島県熊毛郡屋久島町麦生（高平）](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=46&city=1465050&id=159924&merge=)
    - [〒980-6030 宮城県仙台市青葉区中央ＳＳ３０住友生命仙台中央ビル（３０階）](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=4&city=1041010&id=14987&merge=)
- `〜`で丁目・番地等の範囲を指定する場合
  - 例）[〒542-0012 大阪府大阪市中央区谷町（６〜９丁目）](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=27&city=1271280&id=107878&merge=)
- `、`で丁目・番地等を列挙する場合（[2-4](#2-4-町域がで区切られる場合)の②）
  - 例）[〒590-0158 大阪府堺市南区太平寺（５０８−５、６９６−２〜６９６−３、７２４−１、７２５−１、７２６−１、７２７、７２８、７２８−１、７２９、７３０、７３１、７３２、７３３−１〜７３３−２、７３５、７８６−３番地）](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=27&city=1271450&id=108454&merge=1)
- `以上`、`以下`、`以内`、`以外`、`を除く`、`を含む`で範囲や例外を指定する場合
  - 例）[〒996-0301 山形県最上郡大蔵村南山（４３０番地以上「１７７０−１〜２、１８６２−４２、１９２３−５を除く」、大谷地、折渡、鍵金野、金山、滝ノ沢、豊牧、沼の台、肘折、平林）](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=6&city=1063650&id=24561&merge=)
- 入れ子になったカッコ`〔`がある場合
  - 例）[〒979-0622 福島県双葉郡富岡町毛萱（前川原２３２〜２４４、３１１、３１２、３３７〜８６２番地〔東京電力福島第二原子力発電所構内〕）](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=7&city=1075430&id=29776&merge=)

ある程度規則性はありますが、基本的には説明的に補足されている形式になっています。
親切な入力フォームにする場合、例えば[2-4](#2-4-町域がで区切られる場合)と同様に`、`で分割されている部分を別レコードとして扱い、ユーザーに選択させることも考えられますが、

- [〒048-2402 北海道余市郡仁木町大江（１丁目、２丁目「６５１、６６２、６６８番地」以外、３丁目５、１３−４、２０、６７８、６８７番地）](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=1&city=1014070&id=5031&merge=)
- [〒894-1304 鹿児島県奄美市住用町山間（４９３〜５９２番地、戸玉）](https://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=46&city=1462220&id=159369&merge=)

のように`、`で区切られた要素の中で別の特殊な表現が使われている場合もあります。特別ケアしたい事情がなければ、`（）`内の補足情報はすべて削除して扱う形でよいと思います。

## 結局どうすればいいか

以上を踏まえた上で、郵便番号が入力されたら住所（都道府県・市区町村・町域）が補完される入力フォームを作る場合、

- 複数の町域に紐づく郵便番号が入力されていた場合の考慮
  - 都道府県名（[1-2](#1-2-都道府県を跨ぐ場合)）、市区町村名（[1-1](#1-1-市区町村を跨ぐ場合)）まで表示した上で選択させ、セットさせる必要がある
- 町域名を置換する必要がある場合の考慮
  - 末尾2桁が`00`で終わる郵便番号で、町域が「以下に掲載がない場合」 → 町域を削除
  - 町域が「次に」を含む → 町域を削除
  - 町域が「<任意の文字列>一円」を含む → 町域を削除
  - `（）`で補足されている町域 → `（）`内の記述を削除
  - 町域が`、`で区切られている → 町域名を削除するか、`、`で分割して別レコードとして表示した上で選択させる

のような考慮をする必要があります。
実際に郵便番号から住所を取得する部分は外部のライブラリやAPIを利用することも多くあると思いますが、入力フォームを自前で実装する上でも上記の特殊なパターンを考慮したものである必要があります。

## まとめ

システム開発では時には泥臭さも必要。

## 参考

- [郵便番号データの説明 - 日本郵便](https://www.post.japanpost.jp/zipcode/dl/readme.html)
- [ケンオールブログ](https://blog.kenall.jp/)
- [日本郵便の郵便番号データ ken_all をどうにかする - A Memorandum](https://blog1.mammb.com/entry/2020/02/11/015807)

## 最後に

WanoグループではWebエンジニアを募集しています。ご興味のある方は是非、 https://group.wano.co.jp/jobs/ からご応募ください！