概要
正規表現(RegExp)は、文字列に対する検索・抽出・検証のための構文的なパターン言語である。
一方で、「短いが意味の読めない構文」が設計の障害となることも多く、誤検知や過検出・保守不能なブラックボックスを生み出す原因にもなる。
本稿では、以下の観点から正規表現を「設計可能な構文」として再定義する:
- 正規表現の構成要素と基本構文
- 意図を明示するための設計テクニック
- 安全で過不足のない検証パターン
- エスケープ・グルーピング・フラグの管理戦略
- 具体的なユースケース(メール・URL・日付 等)
1. 正規表現の構成と基本構文
const pattern = /[A-Z]{3}-\d{4}/;
pattern.test('ABC-1234'); // true
構文 | 意味 |
---|---|
. |
任意の1文字 |
\d |
数字 ([0-9] ) |
\w |
英数字 ([a-zA-Z0-9_] ) |
+ |
1回以上の繰り返し |
* |
0回以上の繰り返し |
? |
0回または1回 |
^ |
先頭 / 否定(文脈で異なる) |
$ |
末尾 |
(...) |
グルーピング |
` | ` |
2. 正規表現リテラル vs コンストラクタ
const regex1 = /\d+/;
const regex2 = new RegExp('\\d+');
- ✅ 動的に構築する場合はコンストラクタ
- ❌ 二重バックスラッシュが必要で可読性が下がる
3. フラグによる挙動制御
フラグ | 意味 |
---|---|
g |
グローバル(全てに一致) |
i |
大文字・小文字を区別しない |
m |
複数行モード (^ /$ が行単位に) |
/text/gi
4. 読める正規表現の設計戦略
✅ グループ分割してコメントを添える(xフラグ相当の自前ドキュメント)
// ISO日付フォーマット: YYYY-MM-DD
const pattern = /^(\d{4})-(\d{2})-(\d{2})$/;
→ ✅ グループ化で意味を構造化
→ ✅ 必要なら .match()
でキャプチャ使用
5. ユースケース別:安全なパターン設計
✅ メールアドレス(簡易版)
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
→ ❗ RFC準拠ではないが現実的に十分
→ ❌ 極端に複雑なパターン(RFC5322)にはしないこと(保守不能)
✅ URL検出
const urlPattern = /https?:\/\/[^\s/$.?#].[^\s]*/i;
→ ✅ http
, https
両対応
→ ❗ スキーム省略型(www.example.com
)は別対応必要
✅ 数字のカンマ区切り
const numberPattern = /^\d{1,3}(,\d{3})*$/;
→ ✅ 1,000
や 12,345,678
を検出
→ ❌ 1000
は一致しない → 明確なルールを設計に反映
✅ 日付(YYYY/MM/DD)
const datePattern = /^\d{4}\/\d{2}\/\d{2}$/;
→ ✅ 数値とスラッシュの構造を明示
6. エスケープ設計と誤検知回避
const pattern = /https:\/\/example\.com\/user\/\d+/;
→ ✅ .
や /
など、構文上の記号は正しくエスケープすること
→ ❗ 不要な .*
は過検出・ReDoS(正規表現DoS)リスクを高める
7. RegExpを使うべきかの判断指針
① 単純な文字列検出? → includes()/startsWith() で代用可能
② 明確な構造パターンがある? → 正規表現で設計
③ 多数の条件分岐に対応? → 文字列ロジックの方が可読性高い場合も
④ パターンの再利用・キャプチャが必要? → RegExp + match() + group活用
⑤ メンテ可能な構文か? → 複雑な正規表現はドキュメント化必須
よくあるミスと対策
❌ .
や *
を安易に使う
/.*@gmail\.com/ // ❌ 過剰マッチング
→ ✅ [^\s@]+
など、意図を限定する構文で明示
❌ .test()
の副作用に気づかない
const regex = /\d/g;
regex.test('123'); // true
regex.test('123'); // false ❗ カーソル位置が進む
→ ✅ g
フラグ付きで .test()
を繰り返し使うと挙動が変わる → 初期化が必要
結語
正規表現は短く書けるが、読みにくく壊れやすい構文である。
だからこそ、「書くときではなく、読むときの視点で設計すること」が重要になる。
- パターンは構文ではなく、“意味を持った構造”
- 読める構文は、バグを生まない仕様書になる
- ルールを明示し、制限を構造に刻む
ブラックボックスではなく、“意味のある定型”として書かれた正規表現こそが、保守可能な構文である。