正規表現(regular expression, regex)は、文字列のパターン(形)を記述して、「この文字列がそのパターンにマッチするか/どこがマッチするか」を調べたり抽出したり置換したりできるようにする強力な道具です。JavaScript(と多くの言語)では、文字列操作でとてもよく使われます。以下、初心者向けにできるだけ平易に解説します。
全体像・基礎
- 正規表現は パターン であって、単なる文字列との比較より柔軟なマッチを可能にします。
- JavaScript では正規表現はオブジェクト(
RegExpオブジェクト)として扱われ、文字列のメソッドや RegExp のメソッドを使って操作をおこないます。 - パターンは「普通の文字(例えば
"abc")」と「メタ文字(特別な意味を持つ記号)」とを組み合わせて書きます。
正規表現の作り方(生成方法)
JavaScript には主に 2 種類の書き方があります。
| 方法 | 書き方 | 長所・短所など |
|---|---|---|
| リテラル記法(スラッシュ記法) | const re = /abc/; | コード読みやすく、常に一定の正規表現であればこちらを使うことが多いです。 |
| コンストラクタ呼び出し | const re = new RegExp("abc"); | 動的にパターンを生成したいとき(例えば変数やユーザー入力を使って正規表現を作るとき)に便利。ただし、文字列中のエスケープに注意が必要。 |
リテラル方式はスクリプトのロード時に「コンパイル」されるという話もあり、定数的な正規表現には有利とされることがあります。
フラグ(オプション)
正規表現には「フラグ」と呼ばれるモードを指定できるオプションがあり、マッチの挙動を変えられます。
主なものをいくつか紹介します:
| フラグ | 意味 |
|---|---|
g | global(全体検索)。一つマッチしたら終わり、ではなく、複数マッチを探す。 |
i | ignore case(大文字/小文字を無視) |
m | multiline(複数行モード。「^」「$」が行の先頭/末尾にもマッチ) |
s | dotAll(. が改行も含む任意文字としてマッチ可能) |
u | unicode(Unicode コードポイントを意識したマッチができるようになる) |
y | sticky(「現在位置からちょうどマッチする」ことを試す) |
例: /abc/gi は “abc” を大文字小文字を無視して(i)、文字列全体で複数回探す(g)正規表現です。
パターンの構成要素 — 基本
正規表現パターンは「原子(atom)」「量指定子(quantifier)」「文字クラス」「グループ/キャプチャ」「アサーション」などを組み合わせて作ります。
以下、代表的/重要な要素を説明します。
文字クラス・文字集合(Character Classes)
文字クラスを使うと「ある文字たちの集合」の中から「いずれか一文字」にマッチさせられます。
[abc]→'a'または'b'または'c'[a-z]→ 小文字アルファベット a から z まで[0-9]→ 数字 0〜9[^abc]→ a, b, c 以外の文字(否定文字クラス)\d→ 数字(0–9)にマッチ(数字を表すショートカット)\w→ 単語文字(英数字およびアンダースコア)にマッチ\s→ 空白文字(スペース、タブ、改行など)にマッチ
注意点:上記のショートカット(
\d、\w、\sなど)は、Unicode モードや使う環境によって意味が多少変わることがあります。
量指定子(Quantifiers)
量指定子は「直前の要素を何回繰り返すか」を指定します。
*→ 0 回以上(繰り返し可能)+→ 1 回以上?→ 0 回か 1 回{n}→ ちょうど n 回{n,}→ n 回以上{n,m}→ n 回 〜 m 回
例えば、a+ は “a が 1 回以上続く部分” にマッチし、ab*c は “a” の後に “b” が 0 回以上続き、最後に “c” が来るパターンです。
グループ化とキャプチャ(Grouping / Capturing)
丸括弧 () を使って部分パターンをまとめたり、部分一致を「キャプチャ」してあとで参照したりできます。
例:(abc)+ → “abc” が 1 回以上繰り返すパターン(\d{4})-(\d{2})-(\d{2}) → 年-月-日形式(例:2023-07-15)をキャプチャするパターン
「キャプチャされた」部分には、後で「後方参照(backreference)」\1、\2 … でアクセスできます。
アサーション(Assertions)
アサーションは「ある位置がこの条件を満たすかどうかを調べるが、その文字自体は消費しない」ような部分です。
例えば:
^→ 文字列/行の先頭にマッチ$→ 文字列/行の末尾にマッチ(?=…)→ 正先読み:ここから後ろが…にマッチするかをチェック(?!…)→ 否定の先読み:ここから後ろが…にマッチしないかチェック(?<=…)→ 正後読み(JavaScript でサポートがある環境では使える)(?<!…)→ 否定の後読み
例:foo(?=bar) → “foobar” に対して “foo” にマッチするが、“bar” が後続している必要がある^\d+$ → 文字列全体が数字だけでできていることを表す(先頭と末尾、かつ数字のみ)
実際の使い方:マッチ・検索・置換など
正規表現は、主に以下のような手段で文字列処理と組み合わされます。
| メソッド | 用途 | 戻り値・備考 |
|---|---|---|
RegExp.prototype.test(str) | パターンにマッチするかどうかを 真偽値 で返す | true / false。グローバル検索モード(g)の場合、内部の lastIndex が進む起点になることがある(状態を持つ)MDNウェブドキュメント |
RegExp.prototype.exec(str) | マッチした部分とキャプチャ情報を取得 | マッチ情報を含むオブジェクト(配列風)または null |
String.prototype.match(regex) | 文字列に対してマッチ結果を取得 | マッチした部分の配列など(正規表現のフラグによって挙動が変わる) |
String.prototype.replace(regex, replacement) | マッチした部分を別の文字列で置換 | 置換後の新しい文字列を返す |
String.prototype.search(regex) | マッチの最初の位置(インデックス)を返す | 見つからなければ -1 |
String.prototype.split(regex) | 正規表現を区切り文字として文字列を分割 | 分割された文字列の配列を返す |
例:テスト/マッチ例
const regex = /dog/;
console.log(regex.test("I have a dog.")); // true
const dateRegex = /(\d{4})-(\d{2})-(\d{2})/;
const result = dateRegex.exec("2025-10-13");
console.log(result);
// 例:["2025-10-13", "2025", "10", "13", index: 0, input: "2025-10-13", …]
const str = "abc123xyz";
const replaced = str.replace(/\d+/, "NUMBER");
console.log(replaced); // "abcNUMBERxyz"
JavaScriptマッチの挙動に関する注意点・コツ
- 貪欲性 vs 非貪欲性
デフォルトでは量指定子(*、+、{m,n}など)は「できるだけ多くマッチしようとする(貪欲)」挙動をします。
必要に応じて「?」を付けて非貪欲(最小マッチ)にできます:例:.*?は.*より短くマッチしようとする。 - 状態を持つ正規表現
gやyフラグを使った正規表現は、どこまで検索したかを示すlastIndexプロパティを内部に持ちます。これが原因でtest()やexec()を複数回呼ぶとマッチ位置がずれることがあります。 - エスケープ
正規表現で特別な意味を持つ文字(例:*,+,.,?,^,$,(,),[,],{,},|,\)をそのまま文字としてマッチさせたいときはバックスラッシュ\を前につけてエスケープする必要があります。たとえば.は「任意の一文字」にマッチするメタ文字ですが、実際の「ドット文字」にマッチさせたいときは\.と書きます。 - 可読性を意識する
複雑な正規表現は読みにくくバグになりやすいので、必要ならコメント付きで書いたり、小さな部分に分けて組み立てたりすると良いです。
