C# Tips | 文字列処理:郵便番号検証

C# C#
スポンサーリンク

はじめに 「郵便番号検証」は“ゆらぎを受け止めて、きっちり7桁にそろえる”仕事

郵便番号入力って、一見シンプルに見えますよね。
「7桁の数字でしょ?」で終わりそうですが、実務ではそうはいきません。

「1234567」とハイフンなしで入れる人もいれば、
「123-4567」とハイフン付きで入れる人もいる。
中には「123−4567」と全角で入れてくる人もいます。

業務で本当にやりたいことは、

「ユーザーの入力のゆらぎを受け止めて、内部では“正しい7桁の数字”として扱う」

ことです。

ここでは、初心者向けに、

郵便番号の基本ルール
正規表現を使った形式チェック
ハイフン・全角数字を吸収して“7桁に正規化”するユーティリティ
「検証」と「正規化」を分けて設計する考え方

を、例題付きで丁寧に解説していきます。


郵便番号の基本ルールをおさえる

日本の郵便番号の形式

日本の郵便番号は、基本的に「7桁の数字」です。
よく見る表記は「3桁-4桁」、つまり「123-4567」の形です。

なので、機械的なルールとしては、

「数字が7桁あること」
「(あれば)ハイフンの位置は3桁目の後だけ」

この2つを押さえておけば、実務的には十分です。


一番シンプルな「形式チェック」 正規表現で書いてみる

ハイフンあり・なし両方を許可するパターン

まずは、「入力された文字列が郵便番号として“形式的に”正しいか」を見るところから始めます。
ハイフンあり・なし両方を許可する正規表現は、こんな感じで書けます。

using System.Text.RegularExpressions;

public static class PostalCodeValidator
{
    // 1234567 または 123-4567 を許可
    private static readonly Regex PostalCodeRegex =
        new Regex(@"^\d{3}-?\d{4}$", RegexOptions.Compiled);

    public static bool IsValidFormat(string? value)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            return false;
        }

        return PostalCodeRegex.IsMatch(value.Trim());
    }
}
C#

^\d{3}-?\d{4}$ の意味をかみ砕くと、こうなります。

先頭から数字3桁
そのあとにハイフンが「あるかもしれない」(-?
最後に数字4桁
全体で終わり

つまり、「1234567」か「123-4567」だけを許可するパターンです。

動作例で確認する

Console.WriteLine(PostalCodeValidator.IsValidFormat("1234567"));    // true
Console.WriteLine(PostalCodeValidator.IsValidFormat("123-4567"));  // true
Console.WriteLine(PostalCodeValidator.IsValidFormat("1234-567"));  // false
Console.WriteLine(PostalCodeValidator.IsValidFormat("12-34567"));  // false
Console.WriteLine(PostalCodeValidator.IsValidFormat("abc-4567"));  // false
Console.WriteLine(PostalCodeValidator.IsValidFormat(""));          // false
C#

ここまでで、「半角数字+ハイフン」の世界では、形式チェックができるようになりました。


実務で必須になる「正規化」 ハイフンや全角数字を吸収する

ユーザー入力は“きれい”ではない前提で考える

現実の入力は、こんな感じでバラバラです。

「1234567」
「123-4567」
「1234567」
「123−4567」

これらを全部、「内部では 1234567 のような7桁の半角数字」にそろえたい。
そのために必要なのが「正規化(ノーマライズ)」です。

数字だけを抜き出して7桁かどうかを見る

一番シンプルで実務的なやり方は、

「文字列から数字だけを抜き出す → 7桁ならOK」

という考え方です。

using System;
using System.Linq;

public static class PostalCodeNormalizer
{
    public static string NormalizeToDigits(string? value)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            return string.Empty;
        }

        // 全角数字が来る可能性も考えて、いったん全角→半角してから数字だけ抜く、という設計もアリ
        // ここではまず「半角数字だけ」を対象にしたシンプル版を書きます。
        var digits = new string(value.Where(char.IsDigit).ToArray());
        return digits;
    }

    public static bool TryNormalize7Digits(string? value, out string normalized)
    {
        normalized = NormalizeToDigits(value);

        if (normalized.Length != 7)
        {
            return false;
        }

        return true;
    }
}
C#

NormalizeToDigits は、「文字列から数字だけを拾い集めて返す」メソッドです。
TryNormalize7Digits は、「数字だけにしてみて、7桁なら true+正規化済み値を返す」というユーティリティです。

動作例

void Test(string? input)
{
    if (PostalCodeNormalizer.TryNormalize7Digits(input, out var normalized))
    {
        Console.WriteLine($"{input} -> OK: {normalized}");
    }
    else
    {
        Console.WriteLine($"{input} -> NG");
    }
}

Test("1234567");      // 1234567 -> OK: 1234567
Test("123-4567");    // 123-4567 -> OK: 1234567
Test("1234-567");    // 1234-567 -> NG
Test("abc123-4567"); // abc123-4567 -> OK: 1234567(ここを許すかどうかは要件次第)
C#

ここで重要なのは、「数字以外は全部捨てる」という挙動です。
「abc123-4567」も「1234567」として通ってしまうので、
これを許すかどうかは要件次第になります。


全角数字・全角ハイフンも考慮したい場合

全角→半角変換と組み合わせる

日本語環境だと、「123−4567」のような全角入力もよくあります。
これをきちんと扱うには、「全角→半角変換」と組み合わせるのが現実的です。

ここでは、簡易的に「全角数字と全角ハイフンだけ」を半角に寄せる例を示します。

public static class ZenkakuToHankakuUtil
{
    public static string ToHalfWidthDigitsAndHyphen(string value)
    {
        if (string.IsNullOrEmpty(value))
        {
            return value;
        }

        var chars = value.ToCharArray();

        for (int i = 0; i < chars.Length; i++)
        {
            char c = chars[i];

            // 全角数字(0〜9)
            if (c >= '0' && c <= '9')
            {
                chars[i] = (char)('0' + (c - '0'));
            }
            // 全角ハイフンっぽいもの(ー、−、― など)を半角ハイフンに寄せる例
            else if (c == 'ー' || c == '−' || c == '―' || c == '-')
            {
                chars[i] = '-';
            }
        }

        return new string(chars);
    }
}
C#

これを郵便番号の正規化と組み合わせます。

public static class PostalCodeNormalizer
{
    public static bool TryNormalize7DigitsFlexible(string? value, out string normalized)
    {
        normalized = string.Empty;

        if (string.IsNullOrWhiteSpace(value))
        {
            return false;
        }

        // まず全角数字・全角ハイフンを半角に寄せる
        string half = ZenkakuToHankakuUtil.ToHalfWidthDigitsAndHyphen(value);

        // そのうえで数字だけを抜き出す
        string digits = new string(half.Where(char.IsDigit).ToArray());

        if (digits.Length != 7)
        {
            return false;
        }

        normalized = digits;
        return true;
    }
}
C#

動作例

void TestFlexible(string? input)
{
    if (PostalCodeNormalizer.TryNormalize7DigitsFlexible(input, out var normalized))
    {
        Console.WriteLine($"{input} -> OK: {normalized}");
    }
    else
    {
        Console.WriteLine($"{input} -> NG");
    }
}

TestFlexible("1234567");        // OK: 1234567
TestFlexible("123-4567");      // OK: 1234567
TestFlexible("1234567"); // OK: 1234567
TestFlexible("123−4567"); // OK: 1234567
TestFlexible("abc123−4567"); // OK: 1234567(ここを許すかどうかは要件次第)
C#

ここまでやると、「半角/全角」「ハイフンあり/なし」のゆらぎをかなり吸収できます。


「検証」と「正規化」を分けて設計する

形式だけ見るメソッドと、正規化までやるメソッド

実務で長く使うことを考えると、

「入力が“きれいな形式かどうか”だけをチェックするメソッド」
「多少汚くても、7桁に正規化できるかどうかを見るメソッド」

を分けておくと、呼び出し側の意図がはっきりします。

例えば、こんな構成です。

public static class PostalCodeUtil
{
    // 1. きれいな形式(1234567 or 123-4567)かどうか
    public static bool IsCleanFormat(string? value)
        => PostalCodeValidator.IsValidFormat(value);

    // 2. ゆらぎを許容して7桁に正規化できるかどうか
    public static bool TryNormalize(string? value, out string normalized)
        => PostalCodeNormalizer.TryNormalize7DigitsFlexible(value, out normalized);
}
C#

画面やAPI側では、要件に応じて使い分けます。

「入力欄では“きれいな形式”だけ許可したい」なら IsCleanFormat を使う。
「バッチ処理で既存データをできるだけ救いたい」なら TryNormalize を使う。

こうしておくと、「どこまでゆらぎを許すか」を呼び出し側で選べるようになります。


まとめ 「郵便番号検証ユーティリティ」は“人間のゆらぎを受け止めて、機械に優しい7桁にそろえるフィルタ”

郵便番号検証は、「7桁の数字かどうか」を見るだけでは足りません。
実務で本当に効いてくるのは、

ハイフンあり・なしの両方を受け止める
全角数字・全角ハイフンも現実的に扱う
数字だけを抜き出して7桁に正規化する
「形式チェック」と「正規化」を分けて設計する

というあたりです。

ここまで理解できれば、「とりあえず ^\d{7}$ でチェックしている」段階から一歩進んで、
“ユーザー入力のゆらぎを受け止めつつ、内部ではきっちり7桁にそろえる”
業務・実務で本当に使える C# の郵便番号検証ユーティリティを、自分の手で設計・実装できるようになっていきます。

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