Coding

AIで正規表現を作る方法|Pythonで正常例・拒否例を実行する

AIの正規表現案を、全体一致・ASCII数字・末尾改行の条件で検査。Pythonの架空コード13ケースと、広すぎる条件の4例を確認します。

AIものさし編集部

AIに正規表現を作らせるときは、パターンより先に、受け入れる値と拒否する値を決めます。「商品コードをチェックして」だけでは、前後に文章があってもよいのか、全角数字を許すのか、改行を除いてよいのかが決まりません。

この記事では、架空の商品コードをPythonのreで検査します。条件、正規表現、実行コード、結果を一緒に残す方法です。AIへ生成を依頼した実測ではなく、説明用に作ったパターンと入力をローカルのPythonで実行した例です。他の言語や本番システムで動作確認したものではありません。

文字の仕様と、検査する範囲を決める

今回は「ASCII大文字英字3文字、半角ハイフン1文字、ASCII数字3桁」の7文字だけを受け入れます。前後空白や改行を除く処理は行わず、全角から半角への正規化もしません。実際の製品仕様ではありません。

表は横にスクロールできます

条件今回の決め方
目的入力欄全体の形式を検証する
実行環境Python標準のre、文字列str
英字A〜ZのASCII大文字3文字
区切りASCIIのハイフン「-」
数字0〜9のASCII数字3桁
前処理空白削除、大小変換、正規化をしない
抽出今回は不要

入力が「説明文の中からコードを見つける」という目的なら、別の検査です。形式が合っていても、そのコードが商品台帳に存在するかは分かりません。形式検証と、存在・利用権限などの業務上の確認も分けます。

Pythonではfullmatchで全体を確認する

今回のパターンは[A-Z]{3}-[0-9]{3}です。Pythonのfullmatchへ渡し、文字列全体が一致するかを確認します。searchは文字列の途中から探すため、前後に余計な文があっても見つかる場合があります。Python公式:re(新しいタブで開く)

正規表現だけでなく、どのAPIへ、どのフラグで渡すかまで保存してください。同じパターンでも、全体検証と検索を入れ替えると用途が変わります。JavaScriptやPCREなどへ移す場合も、そのまま同じ結果と決めず、移行先の実装で同じ入力を検査します。

次が、この例の受け入れ・拒否条件です。表示上の「改行」「空文字」は説明であり、テストコードでは実際の文字を使います。

表は横にスクロールできます

入力期待確認する条件
ABC-123受け入れる基本形
XYZ-999受け入れる別の大文字と数字
ABC-001受け入れる先頭ゼロを含む数字列
AB-1234拒否英字と数字の桁数が違う
ABC123拒否ハイフンなし
abc-123拒否小文字
ABC-123拒否全角数字
ABC-123拒否全角英字
ABC‐123拒否区切りがASCIIハイフンではない
前に空白があるABC-123拒否前処理で空白を消さない
ABC-123の直後に改行拒否入力全体を検査する
説明文にABC-123を含む拒否部分検索ではない
空文字拒否必須の7文字がない

期待値と実行結果を照合する

次のコードでは、期待値をパターンから作らず、上の仕様から別に用意しています。\nは実行時には改行となり、reprの表示で確認できます。

import re

pattern = re.compile(r"[A-Z]{3}-[0-9]{3}")
cases = [
    ("ABC-123", True),
    ("XYZ-999", True),
    ("ABC-001", True),
    ("AB-1234", False),
    ("ABC123", False),
    ("abc-123", False),
    ("ABC-123", False),
    ("ABC-123", False),
    ("ABC‐123", False),
    (" ABC-123", False),
    ("ABC-123\n", False),
    ("code: ABC-123", False),
    ("", False),
]

for value, expected in cases:
    actual = pattern.fullmatch(value) is not None
    print(repr(value), expected, actual)
    assert actual == expected, repr(value)

このコードの13件は、ローカル実行で期待値と一致しました。実行したPythonのバージョンとケースは検証記録へ残しています。ただし、入力欄、データベース、外部APIとつないだ試験ではありません。13件が通ったことだけで、すべての入力や別の実行環境への適合を保証しません。

広すぎる条件を、拒否例で見つける

数字部分を\d{3}に変えると、PythonのUnicode文字列ではASCII以外の十進数字も対象になります。今回の条件では、全角数字の「ABC-123」を通すと誤りです。数字という言葉だけで、ASCII数字に限定されたと考えないようにします。

また、末尾を表す$は、Pythonでは文字列末尾の改行の直前にも一致します。「先頭と末尾の記号を付けたから、余分な文字は絶対に入らない」という説明だけでは不十分です。Python公式:正規表現の構文(新しいタブで開く)

今回の実行では、次の取り違えも別に確認しました。

表は横にスクロールできます

検査方法入力実行結果今回の仕様との関係
search(r"[A-Z]{3}-[0-9]{3}", ...)code: ABC-123一致あり入力欄全体の検証には使えない
fullmatch(r"[A-Z]{3}-\d{3}", ...)ABC-123一致ありASCII限定の条件より広い
match(r"^[A-Z]{3}-[0-9]{3}$", ...)ABC-123の直後に改行一致あり改行を拒否する条件を満たさない
採用パターンでfullmatchABC-123の直後に改行一致なし今回の拒否条件と一致

これはPythonの指定した方法で実行した結果です。他の言語の数字クラスや末尾記号へ、そのまま一般化しません。生のパターン、文字列への書き方、API、フラグ、入力を一組で確認します。

AIには、未決の条件とテストを返させる

次の仕様の正規表現候補とテストコードを作ってください。
実行環境:[言語・ライブラリ・バージョン]。
目的:入力欄全体の形式検証。部分抽出ではありません。
文字種:ASCII大文字3文字、ASCIIハイフン、ASCII数字3桁。
前処理:空白除去、大小変換、Unicode正規化はしません。
フラグ:追加しないでください。
正常例:ABC-123、XYZ-999、ABC-001。
拒否例:全角文字、小文字、桁違い、空白、末尾改行、説明文、空文字。
出力:パターン、使用API、各条件の説明、期待値付きテストコード。
未決の条件は推測せず列挙してください。
実行していなければ、実行済みとは書かないでください。

仕様で前後空白を許すなら、除去前の値と除去後の値を区別し、前処理のテストも加えます。正規表現を直すのか、入力を変換するのかを曖昧にしないでください。コードの先頭ゼロも、数値へ変換すれば消える場合があるため、識別子の数字列として残します。

形式で扱えない条件と、未検証の負荷を残す

日付の実在、メールの到達、住所の実在などは、形が合うことと別の問題です。複雑な意味条件まで一つの式へ押し込まず、専用の解析や業務上の確認へ分けます。既存システムに検証規則がある場合は、それと競合する式を追加しないようにします。

今回の短い例では、処理時間や大量入力時の負荷を測定していません。「高速」「どんな入力でも安全」とは判断しません。実環境では受け付ける型、最大長、エラー処理、使用エンジンの制限も確認します。

採用時は、条件、パターン、APIとフラグ、実行環境、入力と期待値を一緒に保存します。誤って通した値、正しいのに拒否した値が見つかったら、まず仕様と例へ追加し、以前のケースも含めて再実行してください。AIの説明の読みやすさではなく、決めた条件と実行結果の対応で修正を判断できます。

参考資料

公式仕様の確認日:2026年10月20日。商品コードと入力は架空例です。Pythonの13ケースと取り違え4例をローカルで実行しました。AI生成、別言語、本番入力欄、負荷、業務上のコード存在確認は検証していません。