では先ほどの AI補助バリデーション をさらに進化させて、
入力が間違っている場合に「修正候補」まで提案する版 を作ります。
コンセプト
validate(value, type_)で基本の形式チェック- エラーの場合、
diagnose_errorが 理由と修正候補 を返す - 例えば:
userexample.com→ 「@を追加して user@example.com の形式に」03-123→ 「桁を揃えて 03-1234-5678 の形式に」
完成コード:修正候補付き
import re
# ===== 各種正規表現パターン =====
patterns = {
"email": re.compile(r"^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$", re.VERBOSE),
"phone": re.compile(r"^0\d{1,4}-?\d{1,4}-?\d{3,4}$", re.VERBOSE),
"date": re.compile(r"^(19|20)\d{2}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$", re.VERBOSE),
"url": re.compile(r"^(https?|ftp)://[A-Za-z0-9.-]+(\.[A-Za-z]{2,})+(/[A-Za-z0-9._~:/?#@!$&'()*+,;=%-]*)?$", re.VERBOSE),
"postal": re.compile(r"^\d{3}-?\d{4}$", re.VERBOSE)
}
# ===== AI的エラー診断+修正候補 =====
def diagnose_and_suggest(value: str, type_: str) -> str:
v = value.strip()
if type_ == "email":
if "@" not in v:
return "「@」がありません。例: user@example.com の形式に修正してください。"
if not re.search(r"\.[A-Za-z]{2,}$", v):
return "トップレベルドメインがありません。例: user@example.com の形式に修正してください。"
if " " in v:
return "空白が含まれています。空白を削除してください。"
return "メールアドレスの形式が正しくありません。"
elif type_ == "phone":
digits = re.sub(r"\D", "", v)
if not v.startswith("0"):
suggestion = "0 を先頭に追加すると良いです。例: 03-1234-5678"
return f"電話番号は 0 から始まる必要があります。修正候補: {suggestion}"
if len(digits) < 10:
suggestion = "足りない数字を補ってください。例: 03-1234-5678"
return f"桁数不足です。修正候補: {suggestion}"
return "電話番号形式が不正です。ハイフンの位置を確認してください。"
elif type_ == "date":
parts = v.split("-")
if len(parts) != 3:
return "年月日をハイフンで区切ってください。例: 2025-11-02"
y, m, d = parts
if not (y.isdigit() and m.isdigit() and d.isdigit()):
return "数字以外が含まれています。数字のみで入力してください。"
return "存在しない日付の可能性があります。カレンダーを確認してください。"
elif type_ == "url":
if not re.match(r"^(https?|ftp)", v):
return "URLは http:// または https:// で始めてください。例: https://example.com"
if " " in v:
return "空白が含まれています。削除してください。"
return "URLの形式が不正です。ドメイン名やパスを確認してください。"
elif type_ == "postal":
digits = re.sub(r"\D", "", v)
if len(digits) != 7:
return "郵便番号は7桁必要です。例: 123-4567"
return "郵便番号の形式が不正です。ハイフン位置を確認してください。"
return "不明な入力エラーです。"
# ===== 汎用バリデーション関数 =====
def validate(value: str, type_: str, verbose: bool = True) -> bool:
pattern = patterns.get(type_)
if not pattern:
raise ValueError(f"未知のタイプです: {type_}")
result = bool(pattern.match(value))
if verbose:
if result:
print(f"✅ {type_} OK → {value}")
else:
suggestion = diagnose_and_suggest(value, type_)
print(f"❌ {type_} NG → {value}\n ┗ 修正候補: {suggestion}")
return result
Python使用例(修正候補表示)
validate("userexample.com", "email")
validate("031234567", "phone")
validate("2025-13-40", "date")
validate("python.org", "url")
validate("123456", "postal")
Python出力例
❌ email NG → userexample.com
┗ 修正候補: 「@」がありません。例: user@example.com の形式に修正してください。
❌ phone NG → 031234567
┗ 修正候補: 桁数不足です。修正候補: 足りない数字を補ってください。例: 03-1234-5678
❌ date NG → 2025-13-40
┗ 修正候補: 存在しない日付の可能性があります。カレンダーを確認してください。
❌ url NG → python.org
┗ 修正候補: URLは http:// または https:// で始めてください。例: https://example.com
❌ postal NG → 123456
┗ 修正候補: 郵便番号は7桁必要です。例: 123-4567
特徴
- ❌ 入力ミスの理由をわかりやすく説明
- 💡 修正例を提示 → ユーザーが迷わず直せる
- 📌
verbose=Falseで出力抑制も可能 - すべて Python標準のみ で動作
💡 次の応用アイデア
- 自動修正ボタン:ユーザー入力を自動で候補に変換
- Webフォーム連携:リアルタイムに吹き出しでエラー理由を表示
- 複数タイプ同時チェック:ユーザーID、メール、電話をまとめて検証
