PHP Tips | 文字列処理:フォーマット – 郵便番号フォーマット

PHP PHP
スポンサーリンク

まず「郵便番号フォーマット」でやりたいことをはっきりさせる

業務で郵便番号を扱うとき、だいたいこんな状況になります。

ユーザー入力はバラバラです。

"1234567"
"123-4567"
"123−4567"(全角)
"123 4567"

でも、システムとしてはこうしたいはずです。

  • DB には「統一された形」で保存したい
  • 画面には「見やすい形(123-4567)」で表示したい

つまり、やりたいことは大きく分けて二つです。

1つ目は「余計なものを取り除いて数字だけにそろえること」。
2つ目は「その数字を 123-4567 の形に整えること」。

この二段構えを、PHP のユーティリティ関数としてきれいに分けて考えると、コードがとても分かりやすくなります。


ステップ1:郵便番号から「数字だけ」を取り出す

まずは「正規化」するのが超重要

いきなりハイフンを入れ直そうとするのではなく、
最初に「数字だけの状態」にそろえるのがとても大事です。

理由はシンプルで、入力がどんな形でも、後続の処理を同じ前提で書けるからです。

「数字だけにする」処理を一箇所に閉じ込めておけば、
他の場所で「全角かも」「ハイフンあるかも」と悩まなくて済みます。

全角数字を半角にしてから、数字以外を全部消す

PHP だと、こう書くのが定番です。

/**
 * 郵便番号から数字だけを取り出す(全角数字・ハイフン・空白などを吸収)
 */
function normalizeZipDigits(string $zip): string
{
    // 全角数字を半角に変換
    $zip = mb_convert_kana($zip, 'n', 'UTF-8');

    // 数字以外をすべて削除
    $digits = preg_replace('/[^0-9]/', '', $zip);

    return $digits;
}
PHP

ここでやっていることは二つです。

一つ目は mb_convert_kana($zip, 'n', 'UTF-8') で、全角数字を半角にそろえています。
ユーザーが「1234567」と入力しても、「1234567」に変換されます。

二つ目は preg_replace('/[^0-9]/', '', $zip) で、「数字以外の文字」を全部削除しています。
ハイフン、スペース、全角ハイフンなどはここで消えます。

この関数を通すと、次のように全部同じ結果になります。

echo normalizeZipDigits("1234567");        // 1234567
echo normalizeZipDigits("123-4567");       // 1234567
echo normalizeZipDigits("123−4567"); // 1234567
echo normalizeZipDigits("123 4567");       // 1234567
PHP

ここまで来れば、「あとは7桁の数字」として扱えるので、かなり楽になります。


ステップ2:数字列を「123-4567」の形に整える

桁数チェックをしながらフォーマットする

日本の郵便番号は基本的に「7桁」です。
なので、数字だけにしたあとで「7桁かどうか」を見て、7桁なら 3-4 に分ける、というのが基本形です。

/**
 * 数字だけの郵便番号を 123-4567 形式にフォーマットする
 *
 * 7桁なら 3-4 に分割
 * それ以外はそのまま返す(無理にフォーマットしない)
 */
function formatZipDigits(string $digits): string
{
    if (strlen($digits) !== 7) {
        // 想定外の桁数は、そのまま返す
        return $digits;
    }

    return substr($digits, 0, 3) . '-' . substr($digits, 3, 4);
}
PHP

ここでのポイントは二つあります。

一つ目は、「7桁以外は無理にフォーマットしない」ことです。
桁数がおかしいものをそれっぽく整形してしまうと、バグの原因になります。
「おかしいものはおかしいまま」にしておいた方が、バリデーションで気づきやすいです。

二つ目は、「3桁」と「4桁」に素直に分けているだけ、というシンプルさです。
郵便番号のフォーマットは、電話番号ほど複雑ではないので、これで十分実用的です。


ステップ1+2をまとめた「郵便番号フォーマット」ユーティリティ

生の入力から、いきなり「123-4567」にしてくれる関数

実務では、「ユーザー入力をそのまま渡したら、いい感じに 123-4567 にしてほしい」という場面が多いので、さっきの二つをまとめた関数を用意しておくと便利です。

/**
 * 郵便番号を 123-4567 形式にフォーマットする(生入力対応)
 *
 * 例:
 *   "1234567"        → "123-4567"
 *   "123-4567"       → "123-4567"
 *   "123−4567" → "123-4567"
 *   "123 4567"       → "123-4567"
 */
function formatZip(string $raw): string
{
    // 1. 数字だけに正規化
    $digits = normalizeZipDigits($raw);

    // 2. 7桁なら 3-4 に分割
    return formatZipDigits($digits);
}
PHP

使い方はとてもシンプルです。

echo formatZip("1234567");        // 123-4567
echo formatZip("123-4567");       // 123-4567
echo formatZip("123−4567"); // 123-4567
echo formatZip("123 4567");       // 123-4567
echo formatZip("12345");          // 12345(桁数がおかしいのでそのまま)
PHP

呼び出し側は、「とりあえず formatZip() に通せば、人間が見やすい形になる」と覚えておけばOKです。


バリデーションと組み合わせるとさらに実務向きになる

「フォーマット」と「妥当性チェック」は分けて考える

フォーマットは「見た目を整える」だけで、「正しい郵便番号かどうか」は別問題です。
なので、バリデーション用の関数を別に用意しておくと、設計がきれいになります。

/**
 * 郵便番号として妥当な形式かどうか(簡易チェック)
 *
 * ここでは「数字7桁ならOK」というルールにしている
 */
function isValidZip(string $raw): bool
{
    $digits = normalizeZipDigits($raw);

    return strlen($digits) === 7;
}
PHP

これを組み合わせると、例えばこう書けます。

$input = $_POST['zip'] ?? '';

if (!isValidZip($input)) {
    $error = "郵便番号は数字7桁で入力してください。";
} else {
    $normalized = normalizeZipDigits($input); // DB 保存用(数字だけ)
    $display    = formatZip($input);          // 画面表示用(123-4567)
}
PHP

ここでの大事な考え方は、「保存用」と「表示用」を分けることです。

保存用は「数字だけ」にしておくと検索や比較がしやすく、
表示用は「123-4567」のように人間に優しい形にしておくと UX が良くなります。


実務での使いどころのイメージ

フォーム入力のとき

ユーザーが入力した郵便番号を、確認画面や完了画面で表示するときに、
formatZip() を通しておくと、それだけで見た目が整います。

また、入力欄の初期値として DB に保存してある値を表示するときも、
DB には「数字だけ」を保存しておいて、表示時に formatZipDigits() を通す、というパターンが使えます。

CSV インポート・エクスポートのとき

外部システムとの連携で、郵便番号がバラバラな形式で入ってくることがあります。
そのときに、インポート時に normalizeZipDigits() を通しておけば、
システム内部では常に「数字だけ」で扱えるようになります。

逆に、エクスポート時には formatZipDigits() を通して「123-4567」にして出すと、
人間が見ても分かりやすい CSV になります。


まとめ:今日からの「郵便番号フォーマット」ユーティリティ

大事なポイントだけ、ぎゅっとまとめます。

郵便番号フォーマットは、いきなりハイフンをいじるのではなく、

一つ目に「数字だけに正規化する」。
二つ目に「7桁なら 3-4 に分けて 123-4567 にする」。

この二段構えで考えると、コードがとてもシンプルになります。

実装の核になるのは、この三つです。

function normalizeZipDigits(string $zip): string
{
    $zip = mb_convert_kana($zip, 'n', 'UTF-8');
    return preg_replace('/[^0-9]/', '', $zip);
}

function formatZipDigits(string $digits): string
{
    if (strlen($digits) !== 7) {
        return $digits;
    }
    return substr($digits, 0, 3) . '-' . substr($digits, 3, 4);
}

function formatZip(string $raw): string
{
    return formatZipDigits(normalizeZipDigits($raw));
}
PHP

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