正規表現
文字列のパターンマッチングと置換を行うためのミニ言語
プログラミングテキスト処理
正規表現とは
正規表現 (Regular Expression, Regex) は、文字列のパターンマッチングと置換を行うためのミニ言語である。バリデーション (メールアドレス、電話番号)、テキスト検索、ログ解析で使われる。
基本構文
| パターン | 意味 | 例 |
|---|---|---|
. |
任意の 1 文字 | a.c → abc, aXc |
* |
0 回以上の繰り返し | ab*c → ac, abc, abbc |
+ |
1 回以上の繰り返し | ab+c → abc, abbc |
? |
0 回または 1 回 | colou?r → color, colour |
\d |
数字 | \d{3} → 123 |
\w |
英数字 + アンダースコア | \w+ → hello_123 |
\s |
空白文字 | \s+ → スペース、タブ |
^ |
行頭 | ^Hello |
$ |
行末 | world$ |
[abc] |
a, b, c のいずれか | [aeiou] → 母音 |
(...) |
グループ化 + キャプチャ | (\d{4})-(\d{2}) |
TypeScript での使用
// テスト (マッチするか)
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
emailRegex.test('alice@example.com'); // true
// マッチの抽出
const dateStr = '2026-04-01';
const match = dateStr.match(/^(\d{4})-(\d{2})-(\d{2})$/);
// match[1] = '2026', match[2] = '04', match[3] = '01'
// 置換
'Hello World'.replace(/world/i, 'TypeScript'); // 'Hello TypeScript'
// 全置換
'a-b-c'.replaceAll(/-/g, '_'); // 'a_b_c'
Named Capture Groups
const regex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const { groups } = '2026-04-01'.match(regex)!;
// groups.year = '2026', groups.month = '04', groups.day = '01'
バリデーションでの注意
// ❌ 正規表現だけでメールアドレスを完全にバリデーションするのは困難
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
// ✅ Zod などのバリデーションライブラリを使う
import { z } from 'zod';
const schema = z.object({ email: z.string().email() });
ReDoS (正規表現 DoS)
// ❌ 壊滅的なバックトラッキング
const evil = /^(a+)+$/;
evil.test('aaaaaaaaaaaaaaaaaaaaaaaaaaaaab'); // 数秒〜数分かかる
// ✅ 非バックトラッキングな書き方
const safe = /^a+$/;
ネストした量指定子 ((a+)+) は指数的なバックトラッキングを引き起こす。ユーザー入力に正規表現を適用する場合は ReDoS に注意する。
正規表現を使うべきでないケース
| ケース | 代替 |
|---|---|
| HTML のパース | DOM パーサー |
| JSON のパース | JSON.parse() |
| コードの変換 | AST (ast-grep, jscodeshift) |
正規表現については関連書籍でも詳しく扱われている。