郵便番号チェックは「“7桁の数字っぽいもの”だけを通す」ための技
住所入力フォーム、配送先登録、請求書の宛先設定…。
業務システムで「郵便番号」を扱う場面もかなり多いですよね。
ここで何もチェックしないと、
「123」「abcdefg」「000-0000」みたいな、明らかにおかしい値がDBに入ってしまいます。
後で住所検索が失敗したり、帳票が変な表示になったり、データが汚れたりします。
そこで使うのが 郵便番号チェック。
これは「この文字列が“郵便番号としてあり得る形かどうか”をざっくり判定する」ためのユーティリティです。
完璧な判定ではなく、「明らかにおかしいものを早めにはじくフィルタ」として捉えるのがちょうどいいです。
まずは「日本の郵便番号のざっくりルール」を決める
完璧を目指さず“現場で困らないライン”を決める
日本の郵便番号は、基本的に「7桁の数字」です。
ユーザー入力では、だいたい次の2パターンが多いです。
1234567(ハイフンなし)123-4567(3桁-4桁)
これをベースに、まずはこんなルールを決めてしまうのが現実的です。
数字とハイフン以外は許可しない
ハイフンなしなら 7 桁の数字
ハイフンありなら 3桁-4桁 の形
ここまでチェックすれば、「明らかに郵便番号じゃないもの」はかなり弾けます。
「その番号が本当に存在するか」は別問題なので、まずは“形式”だけを見る、という割り切りが大事です。
シンプルな郵便番号形式チェックユーティリティ
正規表現で「7桁 or 3桁-4桁」を判定する
まずは、よくある2パターンだけを許可するチェックを書いてみます。
import java.util.regex.Pattern;
public final class PostalCodeValidator {
private PostalCodeValidator() {}
// 7桁の数字、または 3桁-4桁
private static final Pattern SIMPLE_JP_POSTAL =
Pattern.compile("^(\\d{7}|\\d{3}-\\d{4})$");
public static boolean isValidFormat(String postalCode) {
if (postalCode == null) {
return false;
}
return SIMPLE_JP_POSTAL.matcher(postalCode).matches();
}
}
Java使い方はこうなります。
System.out.println(PostalCodeValidator.isValidFormat("1234567")); // true
System.out.println(PostalCodeValidator.isValidFormat("123-4567")); // true
System.out.println(PostalCodeValidator.isValidFormat("1234-567")); // false
System.out.println(PostalCodeValidator.isValidFormat("12-34567")); // false
System.out.println(PostalCodeValidator.isValidFormat("123456")); // false
System.out.println(PostalCodeValidator.isValidFormat("12345678")); // false
System.out.println(PostalCodeValidator.isValidFormat("abc-4567")); // false
System.out.println(PostalCodeValidator.isValidFormat("123-45a7")); // false
Javaここで深掘りしたい重要ポイントは三つです。
一つ目は、「正規表現で“許可する形を限定している”」ことです。\\d{7} は「数字7桁」、\\d{3}-\\d{4} は「数字3桁-数字4桁」を表します。(A|B) は「A または B」という意味なので、
「7桁」か「3桁-4桁」のどちらかだけを許可している、ということになります。
二つ目は、「^ と $ で“文字列全体がその形であること”を保証している」ことです。
これがないと、abc1234567xyz のような文字列にもマッチしてしまいます。
形式チェックでは、「全体がその形かどうか」を見るのが基本です。
三つ目は、「null をそのまま false にしている」ことです。
「未入力かどうか」と「形式が正しいかどうか」は、本来別の話なので、
呼び出し側で null や空文字チェックをしたうえで、このメソッドを呼ぶのがきれいな設計です。
ハイフンを抜いた「純粋な7桁」を取り出すユーティリティ
後続処理のために「正規化」しておく
郵便番号を使って住所検索をしたり、外部APIに投げたりするときは、
「ハイフンなしの7桁」で扱うことが多いです。
そこで、「形式チェック」とセットで「正規化(normalize)」のユーティリティを用意しておくと便利です。
public final class PostalCodeUtil {
private PostalCodeUtil() {}
public static String normalizeTo7Digits(String postalCode) {
if (postalCode == null) {
return null;
}
// 空白をトリム
String trimmed = postalCode.trim();
// 形式が正しくなければ null を返す
if (!PostalCodeValidator.isValidFormat(trimmed)) {
return null;
}
// ハイフンを除去して7桁にする
return trimmed.replace("-", "");
}
}
Java使い方はこうです。
System.out.println(PostalCodeUtil.normalizeTo7Digits("1234567")); // 1234567
System.out.println(PostalCodeUtil.normalizeTo7Digits("123-4567")); // 1234567
System.out.println(PostalCodeUtil.normalizeTo7Digits(" 123-4567 "));// 1234567
System.out.println(PostalCodeUtil.normalizeTo7Digits("1234-567")); // null(形式不正)
Javaここでのポイントは、「“チェック”と“正規化”を分けて考える」ことです。
入力フォームでは、
形式が正しいかどうかをチェックしてエラーメッセージを出す
内部処理では、正規化された7桁を使う
という役割分担にしておくと、コードがとても読みやすくなります。
例題:入力フォームでの郵便番号チェック
ユーザー登録フォームで、郵便番号を入力してもらう場面を考えます。
サーバ側では、こんな感じで使えます。
String postal = request.getParameter("postalCode");
if (postal == null || postal.isBlank()) {
errors.add("郵便番号を入力してください。");
} else if (!PostalCodeValidator.isValidFormat(postal.trim())) {
errors.add("郵便番号の形式が正しくありません。(例:1234567 または 123-4567)");
} else {
String normalized = PostalCodeUtil.normalizeTo7Digits(postal);
// normalized は必ず 7桁の数字(または null)なので、DB保存や住所検索に使える
}
Javaここでの重要ポイントは二つです。
一つ目は、「未入力チェック」と「形式チェック」を分けている」ことです。
「入力してください」と「形式が正しくありません」は、ユーザーに伝えたい内容が違うので、
条件もメッセージも分けて書いたほうが親切です。
二つ目は、「チェックに通ったら、すぐに正規化してしまう」ことです。
以降の処理は「7桁の数字だけを扱う」前提で書けるので、
ハイフンの有無や空白を気にしなくて済みます。
「形式チェック」と「実在チェック」は別物だと理解する
郵便番号チェックユーティリティがやっているのは、
あくまで「文字列の形がそれっぽいかどうか」の判定だけです。
1234567 が形式的に正しくても、
その番号が本当に存在するかどうかは分かりません。
実在チェックをしたいなら、
郵便番号データベース(CSVなど)を持って照合する
外部の住所検索APIを叩いてみる
といった別の仕組みが必要になります。
ここで大事なのは、
「形式チェックは“明らかにおかしいものを弾くフィルタ”であって、“正しいことの保証”ではない」
という感覚を持っておくことです。
まとめ:郵便番号チェックユーティリティで身につけたい感覚
郵便番号チェックは、「完璧な判定」を目指すものではなく、
「明らかにおかしいものを早めにはじくためのフィルタ」 です。
まずは、
^(\\d{7}|\\d{3}-\\d{4})$ のようなシンプルな正規表現で
「7桁」か「3桁-4桁」だけを許可する
というところから始めてみてください。
そのうえで、
PostalCodeValidator.isValidFormat で形式をチェックし、PostalCodeUtil.normalizeTo7Digits で7桁に正規化する
という二段構えにしておくと、
入力フォームのバリデーションも、内部処理のロジックも、ぐっと書きやすくなります。
もしあなたのコードのどこかに、
String postal = request.getParameter("postalCode");
// そのままDBに保存
Javaのような箇所があれば、
そこを題材にして、ここで作った isValidFormat と normalizeTo7Digits を一度挟んでみてください。
それだけで、「明らかにおかしい郵便番号がシステムに入り込む」リスクを、かなり減らすことができます。
