JavaScript Tips | 文字列ユーティリティ:検証 - 郵便番号判定

JavaScript JavaScript
スポンサーリンク

郵便番号判定で「何をしたいか」を先に決める

まずゴールをはっきりさせましょう。
ここでやりたいのは、「日本の郵便番号として“それっぽいか”を判定するユーティリティを作ること」です。

日本の郵便番号は、基本的にこういう形をしています。

123-4567
1234567(ハイフンなし)

現実の入力では、これに加えて次のような揺れが混ざります。

全角数字になっている
全角ハイフンになっている
前後にスペースが入っている

なので、業務ユーティリティとしては、

揺れを吸収して「数字7桁」に正規化する
そのうえで「7桁の数字かどうか」を判定する

という二段構えにしておくと、シンプルで実用的です。


ステップ1:郵便番号の「ざっくり構造」を押さえる

日本の郵便番号は、基本的に「数字7桁」です。
よく見る表記は 3桁-4桁 ですが、中身はただの7桁の数字です。

例としてはこうです。

100-00011000001
16000221600022

ここで大事なのは、「ハイフンはあってもなくてもよいが、数字は必ず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

表示するときは、formatPostalCode123-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 と正規表現」から
「意図を持って設計された郵便番号ユーティリティ」に、一段レベルアップします。

タイトルとURLをコピーしました