JavaScriptの正規表現入門——実務でよく使うパターンをコード例で整理する

JavaScriptのRegExpを使った文字列検索・置換・バリデーションの書き方を解説。メールアドレス・電話番号・郵便番号などフォームバリデーションでよく使うパターンをTypeScriptで整理。

正規表現は「なんとなく怖い」と敬遠されがちだが、一度パターンを覚えると文字列操作の生産性が大きく上がる。

フォームバリデーション・ログ解析・テキスト変換など、実務で正規表現を使う場面は思ったより多い。基本から実用パターンまでまとめる。


正規表現の書き方

// リテラル記法(基本はこちらを使う)
const pattern = /hello/;

// コンストラクタ記法(動的にパターンを作るとき)
const word = 'hello';
const dynamicPattern = new RegExp(word, 'i');

フラグ

フラグ意味
gグローバル(全マッチを検索)
i大文字小文字を区別しない
m複数行モード(^$が各行に対応)
s.が改行にもマッチ

基本のメソッド

test — マッチするか確認(boolean)

const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
emailPattern.test('user@example.com'); // true
emailPattern.test('invalid-email');     // false

match — マッチした文字列を取得

const text = '電話番号: 090-1234-5678 または 03-1234-5678';
const phones = text.match(/\d{2,4}-\d{2,4}-\d{4}/g);
// ['090-1234-5678', '03-1234-5678']

replace — 置換

// 全角数字を半角に変換
const fullWidth = '12345';
const halfWidth = fullWidth.replace(/[1-9]/g, (c) =>
  String.fromCharCode(c.charCodeAt(0) - 0xFEE0)
);

// コールバックで動的置換
const template = 'Hello, {name}! You have {count} messages.';
const values = { name: 'Taka', count: '3' };
const result = template.replace(/\{(\w+)\}/g, (_, key) => values[key] ?? '');
// 'Hello, Taka! You have 3 messages.'

split — 分割

// スペース・カンマ・セミコロンのいずれかで分割
'apple, banana;cherry orange'.split(/[,;\s]+/);
// ['apple', 'banana', 'cherry', 'orange']

よく使うバリデーションパターン

// バリデーション関数集
const validators = {
  // メールアドレス
  email: (v: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v),

  // 日本の電話番号(ハイフンあり・なし両対応)
  phone: (v: string) => /^0\d{1,4}-?\d{1,4}-?\d{4}$/.test(v),

  // 郵便番号(123-4567 または 1234567)
  postalCode: (v: string) => /^\d{3}-?\d{4}$/.test(v),

  // URLアドレス
  url: (v: string) => /^https?:\/\/[\w\-._~:/?#[\]@!$&'()*+,;=%]+$/.test(v),

  // パスワード(8文字以上、英大文字・小文字・数字を含む)
  password: (v: string) => /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/.test(v),

  // 半角英数字のみ
  alphanumeric: (v: string) => /^[a-zA-Z0-9]+$/.test(v),
};

// 使い方
validators.email('user@example.com'); // true
validators.password('Passw0rd');      // true
validators.password('password');      // false(大文字・数字なし)

キャプチャグループ

括弧()でグループ化し、マッチした部分を取り出せる。

// 日付文字列を分解する
const dateStr = '2026-07-22';
const match = dateStr.match(/^(\d{4})-(\d{2})-(\d{2})$/);
if (match) {
  const [, year, month, day] = match;
  console.log(year, month, day); // '2026' '07' '22'
}

// 名前付きキャプチャグループ(ES2018+)
const namedMatch = dateStr.match(/^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/);
if (namedMatch?.groups) {
  const { year, month, day } = namedMatch.groups;
}

先読み・後読み

// 肯定先読み: 後ろに特定のパターンが続く場合にマッチ
// 数字の後に「円」が続く場合の数字だけ取得
'1000円 と 500ドル'.match(/\d+(?=円)/g); // ['1000']

// 否定先読み: 後ろに特定パターンが続かない場合にマッチ
'1000円 と 500ドル'.match(/\d+(?!円)/g); // ['100', '500']
// ※ 1000の最後の0が100として取れる挙動に注意

TypeScript でバリデーション関数を型安全に使う

type FieldName = 'email' | 'phone' | 'postalCode';

function validateField(field: FieldName, value: string): string | null {
  const rules: Record<FieldName, { pattern: RegExp; message: string }> = {
    email: { pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, message: '有効なメールアドレスを入力してください' },
    phone: { pattern: /^0\d{1,4}-?\d{1,4}-?\d{4}$/, message: '有効な電話番号を入力してください' },
    postalCode: { pattern: /^\d{3}-?\d{4}$/, message: '有効な郵便番号を入力してください' },
  };

  const rule = rules[field];
  return rule.pattern.test(value) ? null : rule.message;
}

まとめ

メソッド戻り値使い所
test(str)booleanバリデーション
match(pattern)配列 or null文字列抽出
replace(pattern, str)文字列変換・サニタイズ
split(pattern)配列複数区切り文字での分割

最初は「使えそうなパターンをコピペして少し改造する」スタイルで十分だ。よく使うパターンを手元に持っておくと、正規表現が怖くなくなる。

正規表現の詳細はJavaScript本格入門の5.8章(RegExpオブジェクト)で体系的に解説されている。