郵便番号判定で「何をしたいか」を先に決める
まずゴールをはっきりさせましょう。
ここでやりたいのは、「日本の郵便番号として“それっぽいか”を判定するユーティリティを作ること」です。
日本の郵便番号は、基本的にこういう形をしています。
123-45671234567(ハイフンなし)
現実の入力では、これに加えて次のような揺れが混ざります。
全角数字になっている
全角ハイフンになっている
前後にスペースが入っている
なので、業務ユーティリティとしては、
揺れを吸収して「数字7桁」に正規化する
そのうえで「7桁の数字かどうか」を判定する
という二段構えにしておくと、シンプルで実用的です。
ステップ1:郵便番号の「ざっくり構造」を押さえる
日本の郵便番号は、基本的に「数字7桁」です。
よく見る表記は 3桁-4桁 ですが、中身はただの7桁の数字です。
例としてはこうです。
100-0001 → 10000011600022 → 1600022
ここで大事なのは、「ハイフンはあってもなくてもよいが、数字は必ず7桁」ということです。
このルールをベースに判定を組み立てていきます。
ステップ2:全角→半角+ハイフン除去で「数字だけ7桁」にする
全角数字・全角ハイフンを半角にそろえる
日本語入力だと、全角数字や全角ハイフンが普通に混ざります。
123−4567
これをそのまま判定しようとすると面倒なので、
まずは「郵便番号判定用の正規化」として、全角→半角を一度やっておきます。
function toHalfWidth(str) {
if (str == null) return "";
return String(str)
.replace(/[!-~]/g, (ch) =>
String.fromCharCode(ch.charCodeAt(0) - 0xFEE0)
)
.replace(/ /g, " ");
}
JavaScriptこれで、全角英数字・記号・全角スペースを半角に寄せられます。
ハイフンを取り除いて「数字だけ」にする
次に、ハイフンなどの記号を取り除いて、数字だけにします。
function normalizePostalRaw(value) {
if (value == null) return "";
const half = toHalfWidth(value).trim();
// ハイフンを全部削除
const noHyphen = half.replace(/-/g, "");
return noHyphen;
}
JavaScriptここまでで、次のように変換されます。
normalizePostalRaw("123-4567"); // "1234567"
normalizePostalRaw("123−4567"); // "1234567"
normalizePostalRaw(" 1234567 "); // "1234567"
JavaScriptこの「正規化された文字列」をもとに、7桁かどうかを判定します。
ステップ3:「数字7桁かどうか」を判定する
一番シンプルな郵便番号判定
正規化された文字列が「数字7桁」なら OK、そうでなければ NG、という関数を作ります。
function isPostalCode(value) {
const raw = normalizePostalRaw(value);
// 7桁でなければ NG
if (raw.length !== 7) return false;
// 7桁すべてが数字かどうか
return /^\d{7}$/.test(raw);
}
JavaScriptポイントを噛み砕きます。
normalizePostalRaw で「全角→半角+ハイフン除去+trim」まで済ませている。
長さが 7 でなければ、その時点で false。/^\d{7}$/ で「先頭から末尾まで数字7桁だけか」をチェックしている。
これで、「日本の郵便番号として“形式的には”妥当かどうか」を判定できます。
動きの確認
isPostalCode("123-4567"); // true
isPostalCode("1234567"); // true
isPostalCode("123−4567"); // true
isPostalCode("123-456"); // false(桁数不足)
isPostalCode("1234-5678"); // false(桁数多すぎ)
isPostalCode("abc-4567"); // false(数字以外が混ざっている)
JavaScriptここまでで、「明らかにおかしいもの」はかなり弾けます。
応用:正規化した「7桁の数字」を返すユーティリティ
判定だけでなく「きれいな形」も欲しくなる
実務では、「判定して終わり」ではなく、
「DB にはハイフンなし7桁で保存したい」「画面には 123-4567 形式で出したい」
といった要件がよく出てきます。
そのために、「正規化した7桁の数字を返す」ユーティリティを用意しておくと便利です。
function normalizePostalCode(value) {
const raw = normalizePostalRaw(value);
if (!/^\d{7}$/.test(raw)) {
return null; // 郵便番号として不正
}
return raw; // "1234567" のような7桁数字
}
JavaScriptこれを使うと、次のように書けます。
const normalized = normalizePostalCode("123−4567");
// normalized === "1234567"
if (normalized === null) {
// 不正な郵便番号
}
JavaScript表示用に「3桁-4桁」に整形する
保存は「7桁数字」、表示は「3桁-4桁」にしたい場合は、こうします。
function formatPostalCode(raw7) {
if (!/^\d{7}$/.test(raw7)) return raw7;
return raw7.replace(/(\d{3})(\d{4})/, "$1-$2");
}
JavaScript組み合わせると、こんな感じです。
const normalized = normalizePostalCode("123−4567"); // "1234567"
const display = formatPostalCode(normalized); // "123-4567"
JavaScriptこれで、「入力の揺れを吸収しつつ、保存と表示をきれいに分ける」ことができます。
業務での具体的な使いどころ
フロントエンドの入力チェック
フォームで郵便番号を入力してもらうとき、
「明らかにおかしいもの」を早めに教えてあげる用途です。
const postal = postalInput.value;
if (!isPostalCode(postal)) {
showError("郵便番号は 123-4567 または 1234567 の形式で入力してください。");
}
JavaScriptここでのポイントは、
「ユーザーの入力ミスを減らすためのガイド」として使う、という意識です。
バックエンド側の保存前正規化
DB には「ハイフンなし7桁」で統一して保存しておくと、
検索や連携がとても楽になります。
const normalized = normalizePostalCode(input.postalCode);
if (normalized === null) {
throw new Error("Invalid postal code");
}
// DB には normalized(例: "1234567")を保存
JavaScript表示するときは、formatPostalCode で 123-4567 に戻せばOKです。
設計として意識してほしいこと
「正規化」と「判定」と「表示」を分ける
ここが一番大事なポイントです。
全角→半角+ハイフン除去(normalizePostalRaw)
7桁数字かどうかの判定(isPostalCode / normalizePostalCode)
表示用のフォーマット(formatPostalCode)
これらは、役割が違う処理です。
全部を一つの関数に詰め込むと、
「この関数、何をどこまでやるんだっけ?」と分かりづらくなります。
なので、段階ごとに関数を分けておくと、
テストもしやすいし、仕様変更にも強くなります。
「どのタイミングで正規化するか」を決める
入力直後に正規化するのか。
保存前に正規化するのか。
検索前や出力前だけ正規化するのか。
これはシステム設計の話ですが、
大事なのは「ブレさせない」ことです。
個人的には、
保存するデータは「ハイフンなし7桁」に統一する
画面表示のときだけ 123-4567 にフォーマットする
という方針が、扱いやすくておすすめです。
ちょっとだけ手を動かしてみる
コンソールで、次のあたりを試してみてください。
normalizePostalRaw("123−4567");
isPostalCode("123-4567");
isPostalCode("123456");
normalizePostalCode("123−4567");
formatPostalCode("1234567");
JavaScript「どこからが true で、どこからが false になるか」
「入力がどう正規化されて、どう表示用に整えられるか」
を体で感じてみてください。
そのうえで、自分のプロジェクトに
export function normalizePostalRaw(value) { ... }
export function isPostalCode(value) { ... }
export function normalizePostalCode(value) { ... }
export function formatPostalCode(raw7) { ... }
JavaScriptのようなユーティリティを一つ置いて、
「郵便番号を触るときは必ずここを通す」
というルールにしてみてください。
それができた瞬間、あなたの検証処理は
「その場しのぎの if と正規表現」から
「意図を持って設計された郵便番号ユーティリティ」に、一段レベルアップします。
