D-01 「1-2-3」と「一丁目2番地3号」は同じ場所 ―― 番地の表記ゆれ 症状:同じ住所なのに書き方が違うだけで「別の住所」として扱われ、重複登録・配送照合ミス・本人確認の不一致が起きる。
体験デモ:登録済み住所「1-2-3」と、あなたの入力を突き合わせる
一丁目2番地3号 1−2−3(全角) 1丁目2-3
単純な文字列一致での突合 -
正規化してから突合(簡易再現) -
※デモの正規化は漢数字・区切り語・ハイフン類だけを吸収する簡易版です。実際の住所正規化はもっと奥が深い(だからこそ自前で書かない、が本エントリの結論です)。
なぜ起きるか
日本の住所には公式の「正規形」が事実上存在せず、「1-2-3」「1−2−3」「一丁目2番地3号」「1丁目2番3号」はすべて正しい書き方です。
人間は同じ場所だと分かりますが、文字列としては全部別物。これが重複顧客の温床であり、住所を突合するあらゆる業務(配送・名寄せ・本人確認)の古典的な難所です。
正しい実装 // 住所の表記ゆれ吸収を、自前の正規表現で頑張らない
// 実績のあるOSSや住所正規化サービスに寄せるのが現実解
// 例:geolonia/normalize-japanese-addresses(オープンソース)
const r = await normalize('京都府京都市中京区寺町通御池上る上本能寺前町488');
// → 都道府県・市区町村・町字・番地に構造化して返してくれる
// 自前でやるのは「比較の前にNFKC正規化+空白除去」程度に留める 入力欄の設計としては「表記ゆれをエラーにしない」が第一原則。どの書き方でも受け取り、揃える処理はシステム側の責務にする。
現実の被害
「ご登録の住所と一致しません」で本人確認に落ちる、同一人物が別顧客としてカウントされてDM二重送付――住所ゆれの被害は入力時ではなく、あとから業務側に出ます。
D-02 郵便番号→住所補完は「便利機能」であって「検証」ではない 症状:実在する郵便番号なのに「郵便番号が正しくありません」と言われる。補完された住所が実際と違う。
体験デモ:郵便番号補完の3つのシナリオ
一般の郵便番号 大口事業所の個別番号 新設・辞書更新前の番号
住所辞書の応答 -
「辞書ヒット必須」フォームの挙動 -
※シナリオの再現デモです(実際の郵便番号データベースは同梱していません)。
なぜ起きるか
郵便番号辞書は「町域」を引くためのものですが、現実には例外が多くあります。大口事業所には個別の郵便番号が割り当てられており(全国に約2万件規模)、通常の町域辞書に無いか、辞書によって収録が異なります。新設の番号や辞書の更新遅れもある。
つまり「辞書にヒットしない=不正な郵便番号」ではありません 。
正しい実装 // 郵便番号は「直してから」チェック。住所補完は「提案」に留める
const zip = value.normalize('NFKC').replace(/[^0-9]/g, '');
if (!/^\d{7}$/.test(zip)) {
// ここで初めてエラー(ハイフン有無・全角はこの時点で吸収済み)
}
// 補完した住所は必ず編集可能にする。
// 大口事業所の個別番号・新設番号・辞書の更新遅れがあるため、
// 「辞書にヒットすること」を登録の必須条件にしない 現実の被害
大口事業所番号を使う企業の担当者(=B2Bの発注元)が、自社の正式な郵便番号で登録できない。補完が「提案」ではなく「強制」だと、正しい住所を知っている本人が直せません。
D-03 京都の住所には「通り名」がある ―― 定型欄に入らない正式住所 症状:「寺町通御池上る」のような通り名を書く欄がなく、書けば文字数制限に当たり、省けば正式な住所ではなくなる。
なぜ起きるか
京都市の中心部では「寺町通御池上る」のように、通りとの位置関係で場所を示す表記が正式に使われています。当然、住所は長くなります。
「町名は10文字程度」「番地欄は20文字もあれば十分」という感覚値で文字数制限を切ると、京都の正式住所は入りません。しかも京都には同じ町名が複数の区に存在する ため、通り名を省くと特定性が下がる場合があります。
正しい実装
住所欄の文字数制限は「想定の2倍」ではなく、制度上あり得る長さから決める(都道府県から建物名まで含めれば100文字を超える住所は普通に存在します)。欄を分割する場合も、通り名・字(あざ)・方書きの置き場を潰さない。A-05(氏名の文字数)と同じ話です――制限の根拠を言えないなら、その制限は不要です 。
現実の被害
京都市中心部の事業者・住民が正式住所で登録できない。切り詰められた住所は配送・請求書送付の事故になり、「住所が変です」の問い合わせ対応コストとして返ってきます。
D-04 「丁目・番・号」が存在しない住所 ―― 分割欄の破綻 症状:丁目・番・号の3分割欄(各必須・数字のみ)に、丁目のない住所の人が入力できない。
体験デモ:丁目・番・号がすべて必須のフォーム
「大字○○123番地」の人として入力 北海道の「○線○号」の人として入力 この内容で登録
なぜ起きるか
「丁目・番・号」は住居表示が実施された市街地の型です。地方には「大字+番地」だけの住所が広くあり、北海道の農村部には「西5線北12号」のような線・号で表す住所も実在します。
都市部の住所の型を全国に強制する設計は、A-04(姓名分割の強制)と同じ構造の思い込みです。
正しい実装
住所の細部を構造化して受けたい要件(配送の機械処理など)が本当にあるか、まず疑う。多くのフォームでは「市区町村まで」+「それ以降は自由記述1欄」 で足ります。構造化が必要でも、丁目・番・号を必須にしない。
現実の被害
該当地域の住民は毎回、欄のどこかに嘘(ダミーの「1」など)を書いて通すことになります。フォームが嘘の入力を強制している――バリデーションの目的と真逆の結果です。
D-05 郵便番号のハイフン・全角も「直せる入力」 症状:「123-4567」と入れると「ハイフンなしで」と怒られ、「1234567」と入れると「半角で」と怒られる。
体験デモ:弾くフォーム vs 直すフォーム
ハイフン付き 全角 7桁半角
弾くフォームの応答(7桁半角数字のみ許可) -
直すフォーム(正規化)の結果 -
なぜ起きるか
郵便番号の公式表記はそもそも「123-4567」のハイフン付きです。ハイフンを弾くフォームは、正式な書き方をエラーにしている ことになります。全角はB-04・C-02と同じ話で、NFKC正規化1行の問題。
正しい実装
ハイフン・全角を吸収してから7桁チェック(コードはD-02のスニペット参照)。inputmode="numeric" で数字キーボードを出し、autocomplete="postal-code" でブラウザの自動入力を活かす。そして辞書ヒットを必須にしない(D-02)。
現実の被害
郵便番号はほぼ全フォームにある入力欄=この摩擦は全ユーザーが通る道です。ハイフン許容と正規化だけで、フォーム全体の離脱が目に見えて変わる箇所でもあります。