正規表現 コピペで使える実践 Tips 集【中級者向け】

正規表現 コピペで即使えるパターンを、実務でよく遭遇するケース別にまとめた。基本文法は知っているが「あのパターンどう書くんだっけ」と詰まる中級者向けのリファレンス記事だ。

正規表現 コピペで使えるパターン集

メールアドレス

const EMAIL = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\.[a-zA-Z]{2,}$/;

EMAIL.test("[email protected]");       // true
EMAIL.test("[email protected]"); // true
EMAIL.test("user@");                  // false

URL

const URL_PATTERN = /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_+.~#?&/=]*)$/;

URL_PATTERN.test("https://example.com/path?q=1#hash"); // true
URL_PATTERN.test("http://localhost:3000");              // true
URL_PATTERN.test("ftp://example.com");                 // false

日付(YYYY-MM-DD)

const DATE_YMD = /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/;

DATE_YMD.test("2026-06-19"); // true
DATE_YMD.test("2026-13-01"); // false
DATE_YMD.test("2026-6-1");   // false

電話番号(日本)

// ハイフンあり・なし両対応(固定・携帯)
const JP_PHONE = /^0(?:\d-\d{4}|\d{2}-\d{3}|\d{3}-\d{2}|\d{4}-\d|\d{9}|\d{2}-\d{4}|\d{4}-\d{4})\d{4}$|^0[789]0-\d{4}-\d{4}$|^0[789]0\d{8}$/;

JP_PHONE.test("090-1234-5678"); // true
JP_PHONE.test("03-1234-5678");  // true
JP_PHONE.test("09012345678");   // true

郵便番号(日本)

const JP_POSTAL = /^\d{3}-?\d{4}$/;

JP_POSTAL.test("100-0001"); // true
JP_POSTAL.test("1000001");  // true
JP_POSTAL.test("10-001");   // false

クレジットカード番号(簡易)

const CREDIT_CARD = /^\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}$/;

CREDIT_CARD.test("4111111111111111");      // true
CREDIT_CARD.test("4111-1111-1111-1111"); // true

IPv4 アドレス

const IPV4 = /^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/;

IPV4.test("192.168.0.1");   // true
IPV4.test("256.0.0.1");     // false
IPV4.test("192.168.0.256"); // false

名前付きキャプチャグループ(?<name>

名前付きキャプチャグループを使うと、match.groups でキャプチャ結果に名前でアクセスできる。インデックス管理が不要になり、正規表現を修正してもコードが壊れにくい。

const DATE_PATTERN = /(?<year>\d{4})-(?<month>0[1-9]|1[0-2])-(?<day>0[1-9]|[12]\d|3[01])/;

const match = "2026-06-19".match(DATE_PATTERN);
const { year, month, day } = match.groups;
// year  → "2026"
// month → "06"
// day   → "19"

名前付きグループを replace で参照するには $<name> を使う。

const result = "2026-06-19".replace(
  /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/,
  "$<day>/$<month>/$<year>"
);
// → "19/06/2026"

replaceAll に関数を渡すパターン。

const log = "Error at 2026-06-19, Warning at 2026-06-20";

const formatted = log.replaceAll(
  /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/g,
  (_, _y, _m, _d, _offset, _str, groups) =>
    `${groups.day}/${groups.month}/${groups.year}`
);
// → "Error at 19/06/2026, Warning at 20/06/2026"

Lookahead / Lookbehind

ゼロ幅アサーションは「前後の文字を条件にしつつ、マッチに含めない」ときに使う。

Positive lookahead (?=...)

// 数字の後に "px" が続く数値だけにマッチ
const pxValues = "10px 20em 30px".matchAll(/\d+(?=px)/g);
[...pxValues].map(m => m[0]); // ["10", "30"]

Negative lookahead (?!...)

// "foo" の後に "bar" が続かない場合にマッチ
const re = /foo(?!bar)/g;
"foobar foobaz".match(re); // ["foo"]  ← "foobaz" の "foo" だけ

Positive lookbehind (?<=...)

// "$" の後に続く数値にマッチ
const prices = "$100 €200 $300".matchAll(/(?<=\$)\d+/g);
[...prices].map(m => m[0]); // ["100", "300"]

Negative lookbehind (?<!...)

// "!" が前に来ない "important" にマッチ
const re = /(?<!!)important/g;
"important !important also important".match(re); // ["important", "important"]

実用例: パスワード強度チェック

function validatePassword(pw) {
  const hasUpper   = /(?=.*[A-Z])/.test(pw);
  const hasLower   = /(?=.*[a-z])/.test(pw);
  const hasDigit   = /(?=.*\d)/.test(pw);
  const hasSpecial = /(?=.*[!@#$%^&*])/.test(pw);
  const minLength  = pw.length >= 8;
  return hasUpper && hasLower && hasDigit && hasSpecial && minLength;
}

validatePassword("Passw0rd!");  // true
validatePassword("password");   // false

フラグの使い分け

フラグ意味典型的な用途
gグローバル(全マッチ)matchAll / replaceAll
i大文字小文字無視HTML タグ、ユーザー入力
m複数行(^/$ が行頭・行末に)複数行テキストのパース
sdotAll(. が改行を含む)HTML/JSON の抽出
uUnicode モード絵文字・多言語テキスト
dインデックス取得(ES2022)マッチ位置の特定
// m フラグ: 行ごとの先頭にある ">" を除去(Markdown 引用解除)
const quoted = "> Hello\n> World";
quoted.replace(/^> /gm, ""); // "Hello\nWorld"

// s フラグ: 複数行にまたがる <script> タグを除去
const html = "<script>\nalert(1);\n</script>";
html.replace(/<script>.*?<\/script>/gs, ""); // ""

// u フラグ: 絵文字を分割せずカウント
const str = "Hello 👋 World";
[...str.matchAll(/\p{Emoji}/gu)].length; // 1(uなしだと誤カウントの恐れ)

String.prototype.matchAll の活用

matchg フラグを付けるとキャプチャグループが消える。matchAll はイテレータを返し、各マッチのキャプチャグループを保持する。

const text = "2026-01-15, 2026-06-19, 2026-12-31";
const re = /(\d{4})-(\d{2})-(\d{2})/g;

// match + g フラグ → キャプチャグループが取れない
text.match(re); // ["2026-01-15", "2026-06-19", "2026-12-31"]

// matchAll → 全マッチのキャプチャグループを取得できる
const dates = [...text.matchAll(re)].map(([, year, month, day]) => ({
  year, month, day,
}));
// [
//   { year: "2026", month: "01", day: "15" },
//   { year: "2026", month: "06", day: "19" },
//   { year: "2026", month: "12", day: "31" },
// ]

名前付きキャプチャグループと組み合わせると可読性が上がる。

const LOG = /\[(?<level>INFO|WARN|ERROR)\] (?<message>.+)/g;
const logs = `[INFO] Server started
[WARN] High memory usage
[ERROR] Connection refused`;

for (const { groups } of logs.matchAll(LOG)) {
  console.log(groups.level, groups.message);
}
// INFO   Server started
// WARN   High memory usage
// ERROR  Connection refused

正規表現のパフォーマンス注意点

ループ内での new RegExp を避ける

// Bad: ループごとにコンパイルが走る
function findBad(items, keyword) {
  return items.filter(item => new RegExp(keyword, "i").test(item));
}

// Good: 外でコンパイルしてキャッシュ
function findGood(items, keyword) {
  const re = new RegExp(keyword, "i");
  return items.filter(item => re.test(item));
}

カタストロフィックバックトラック(ReDoS)に注意

// 危険: ネストした量指定子
// /^(a+)+$/ → "aaaaaaaaaaaaaaab" で指数的バックトラック

// 安全: アトミックグループ相当の書き換え(possessive はJS未対応のため代替)
// /(a+)/ → 内部で重複しないよう設計する

// 実例: メールの簡易チェックで使いがちなパターン
// Bad:  /^([a-zA-Z0-9]+)*@/
// Good: /^[a-zA-Z0-9._%+-]+@/

test vs match vs exec の使い分け

const str = "Hello World";
const re = /world/i;

// 存在確認だけなら test が最速
re.test(str); // true

// キャプチャグループが必要なら exec(g フラグを使いまわすときも exec)
const re2 = /(\w+)/g;
let m;
while ((m = re2.exec(str)) !== null) {
  console.log(m[1], m.index);
}
// Hello 0
// World 6

lastIndex のリセット忘れに注意

const re = /\d+/g;

re.test("abc123"); // true  → lastIndex = 6
re.test("456def"); // false → lastIndex が 6 から再開されて見逃す

// 毎回リセットするか、test には /g を付けないのが安全
re.lastIndex = 0;
re.test("456def"); // true

まとめ

Tipsポイント
よく使うパターン集メール・URL・日付・電話番号はそのままコピペ可。要件に合わせて微調整する
名前付きキャプチャグループ(?<name>...) + groups.name でインデックス管理が不要に。replace では $<name>
Lookahead / Lookbehind(?=...) (?!...) (?<=...) (?<!...) でゼロ幅アサーション。パスワード検証に特に有効
フラグの使い分けg は全マッチ、i は大文字無視、m は複数行、s はdotAll、u はUnicode
matchAll の活用g フラグ + キャプチャグループが必要なら matchAll 一択。スプレッドで配列化
パフォーマンスループ外でコンパイル・ReDoSパターンを避ける・g フラグの lastIndex に注意

正規表現は書き捨てにせず、定数として切り出してテストを添えておくと長期的なメンテが楽になる。vitestjest で各パターンにスナップショットテストを書いておくのがおすすめだ。