正規表現

文字列のパターンマッチングと置換を行うためのミニ言語

プログラミングテキスト処理

正規表現とは

正規表現 (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)

正規表現については関連書籍でも詳しく扱われている。

関連用語