正規表現(Regular Expression)とは、文字列のパターンを記号で表現する記法で、検索・置換・バリデーションに使われる。基本メタ文字は .(任意の1文字)、*(0回以上)、+(1回以上)、?(0か1回)、[](文字クラス)の5つ。JavaScriptでは /パターン/フラグ のリテラル記法か new RegExp() で生成し、test()・match()・replace()メソッドで活用する。
正規表現とは
正規表現(Regular Expression、略して regex または regexp)は、文字列のパターンを表現するための記法だ。特定の文字の並びを「パターン」として定義し、文字列の検索・抽出・置換・バリデーションを柔軟かつ効率的に行える。
どんな場面で使うか
正規表現はプログラミングに限らず、テキストエディタやコマンドラインツール(grep、sed、awk)でも日常的に使われる。具体的な場面を挙げる。
- フォーム入力値のバリデーション(メールアドレス・電話番号・郵便番号の形式確認)
- ログファイルから特定のエラーメッセージや日付を抽出する
- HTMLやCSVなどのテキストデータを一括置換・整形する
- URLの構造解析やルーティング設定(Express・Nginxなど)
- コードエディタ(VS Code・Sublime Text)での高度な検索・置換
- Webスクレイピングで必要なデータだけを取り出す
Point
正規表現はほぼすべてのプログラミング言語でサポートされており、一度習得すれば言語をまたいで応用が利く。構文に若干の差異はあるが、コアとなる考え方は共通だ。
基本メタ文字一覧
正規表現では通常の文字に加え、特別な意味を持つ「メタ文字」を使う。まず頻出の10個を頭に入れておけば、実務のほとんどのケースに対応できる。
| メタ文字 | 意味 | 例 | マッチする文字列 |
|---|---|---|---|
. |
任意の1文字(改行以外) | a.c |
abc, aXc, a1c など |
* |
直前の要素が0回以上繰り返す | ab*c |
ac, abc, abbc, abbbc など |
+ |
直前の要素が1回以上繰り返す | ab+c |
abc, abbc(ac は非マッチ) |
? |
直前の要素が0回または1回 | colou?r |
color, colour |
^ |
行頭にマッチ | ^Hello |
"Hello world"(先頭から始まる行) |
$ |
行末にマッチ | world$ |
"Hello world"(末尾で終わる行) |
[] |
文字クラス(いずれか1文字) | [aeiou] |
a, e, i, o, u のいずれか |
() |
グループ化・キャプチャ | (ab)+ |
ab, abab, ababab など |
| |
OR(選択) | cat|dog |
cat または dog |
\ |
エスケープ(次の文字を文字通りに解釈) | \. |
ピリオド文字そのもの |
注意
メタ文字そのものを検索したいときはバックスラッシュでエスケープする。たとえばピリオド(.)を文字として検索するには \. と書く。( ) [ ] { } ^ $ * + ? | \ / などは要エスケープ。これを忘れて意図しないマッチが発生するのは初心者あるあるだ。
文字クラス(\d, \w, \s, \b)
よく使う文字のグループには省略記法の「定義済み文字クラス」が用意されている。[] でいちいち書くより大幅に簡潔になるため、積極的に使いたい。
| 記法 | 意味 | 同等の表現 | 大文字(否定形) |
|---|---|---|---|
\d |
数字(0〜9) | [0-9] |
\D(数字以外) |
\w |
単語文字(英数字+アンダースコア) | [a-zA-Z0-9_] |
\W(単語文字以外) |
\s |
空白文字(スペース・タブ・改行など) | [ \t\n\r\f\v] |
\S(空白以外) |
\b |
単語境界(単語の開始・終了位置) | — | \B(単語境界以外) |
\t |
タブ文字 | — | — |
\n |
改行文字(LF) | — | — |
文字クラスの範囲指定
[] 内では - を使って範囲を指定できる。^ を先頭に置くと否定クラス(「〜以外」の意味)になる。
量指定子
量指定子(Quantifiers)は直前の要素が「何回繰り返すか」を指定するものだ。* + ? の3つが基本で、さらに具体的な回数も指定できる。
| 量指定子 | 意味 | 例 | マッチ例 |
|---|---|---|---|
* |
0回以上 | \d* |
""(空), "1", "123" |
+ |
1回以上 | \d+ |
"1", "123"(空は非マッチ) |
? |
0回または1回 | \d? |
""(空), "1" |
{n} |
ちょうどn回 | \d{4} |
"2026"(4桁の数字) |
{n,} |
n回以上 | \d{3,} |
"123", "1234", "12345"… |
{n,m} |
n回以上m回以下 | \d{2,4} |
"12", "123", "1234" |
最長マッチと最短マッチ
デフォルトの量指定子は「最長マッチ(greedy)」で、できるだけ多くの文字にマッチしようとする。量指定子の後に ? を付けると「最短マッチ(lazy)」に切り替わり、できるだけ少ない文字にマッチするようになる。
Point
HTMLタグのパターンを書くときは最短マッチ(+? や *?)を使うことが多い。ただし複雑なHTMLのパースには正規表現より専用のパーサを使うほうが安全だ。
グループ化とキャプチャ
括弧 () を使うと複数の要素を一つのグループとして扱える。グループ化には「繰り返し単位の指定」と「キャプチャ(一致した部分の取り出し)」という2つの役割があり、これを使いこなせると正規表現が一段と強力になる。
グループ化で繰り返し単位を指定
キャプチャグループ
グループ化した部分はキャプチャグループとして後から参照できる。日付フォーマットの変換など、マッチ結果を加工する処理でよく使うパターンだ。
非キャプチャグループ
キャプチャせずにグループ化だけしたい場合は (?:...) を使う。不要なキャプチャを省くとパフォーマンスが向上するため、取り出す必要のない括弧は非キャプチャグループにする習慣をつけておくといい。
先読み・後読み
特定のパターンの「前後に何があるか」を条件として使う「ゼロ幅アサーション」も強力だ。一致した文字自体はキャプチャせず、位置だけを判定できる。
| 記法 | 種類 | 意味 |
|---|---|---|
(?=...) |
肯定先読み | 直後に指定パターンがある位置 |
(?!...) |
否定先読み | 直後に指定パターンがない位置 |
(?<=...) |
肯定後読み | 直前に指定パターンがある位置 |
(?<!...) |
否定後読み | 直前に指定パターンがない位置 |
Web制作でよく使う正規表現パターン20選
ここからは実務で即使えるパターンを20個まとめた。各パターンにはマッチ例と簡潔な解説を添えている。そのままコピーして正規表現テスターで動作確認しながら、構造を少しずつ読み解いていくと身につきやすい。なお、メールアドレスのパターンについては後述のFAQに補足があるので合わせて確認してほしい。
バリデーション系
1. メールアドレス
2. 電話番号(日本・固定電話&携帯)
3. 携帯番号(日本)
4. 郵便番号(日本)
5. URL
6. IPアドレス(IPv4)
テキスト処理系
7. HTMLタグ除去
8. 空白行の削除
9. 先頭・末尾の空白除去(トリム)
10. 全角スペースの検出
11. 連続する空白を1つに
抽出系
12. YouTube動画ID
13. X(Twitter)ユーザー名
14. ハッシュタグ
15. 日付(YYYY-MM-DD形式)
16. 金額(日本円)
バリデーション系(応用)
17. パスワード強度チェック(8文字以上・英数字混在)
18. クレジットカード番号(16桁)
置換系
19. カンマ区切り数値への変換
20. キャメルケースからスネークケースへの変換
日本語文字の検出
Web制作では日本語テキストの検出やバリデーションも頻出する。Unicode範囲指定を使ったパターンも覚えておこう。
ツールで効率化
上記のパターンはすべて当サイトの正規表現テスターで動作確認できる。パターンをコピーしてテスターに貼り付け、テスト文字列を入力するだけでマッチ結果がリアルタイムに表示される。
JavaScriptでの正規表現の使い方
Web制作において最も使用頻度が高いJavaScriptでの正規表現の使い方を詳しく解説する。リテラル記法からメソッドの使い分け、フラグの意味、ES2018で追加された名前付きキャプチャグループまで、実務で必要な知識をまとめた。
正規表現の2つの記法
主要メソッド一覧
| メソッド | 返り値 | 用途 |
|---|---|---|
regex.test(str) |
true / false | マッチするかどうかの判定 |
str.match(regex) |
配列 / null | マッチした文字列の取得 |
str.matchAll(regex) |
イテレータ | 全マッチのキャプチャグループ含む取得 |
str.replace(regex, rep) |
文字列 | マッチ箇所の置換 |
str.replaceAll(regex, rep) |
文字列 | 全マッチ箇所の置換(gフラグ必須) |
str.search(regex) |
インデックス / -1 | 最初のマッチ位置の取得 |
str.split(regex) |
配列 | パターンで文字列を分割 |
実務コード例
フラグ(修飾子)
| フラグ | 名称 | 効果 |
|---|---|---|
g |
global | 全マッチを検索(最初の1件で止まらない) |
i |
ignoreCase | 大文字・小文字を区別しない |
m |
multiline | ^ $ が各行の先頭・末尾にマッチ |
s |
dotAll | . が改行文字にもマッチ |
u |
unicode | Unicodeコードポイントとして処理(日本語で推奨) |
名前付きキャプチャグループ(ES2018+)
ES2018で追加された名前付きキャプチャグループを使うと、キャプチャした値に名前でアクセスできる。$1, $2 のような番号より可読性が高く、パターンが複雑になっても保守しやすい。
Point
名前付きキャプチャグループはIE11では非対応だが、モダンブラウザ(Chrome 64+、Firefox 78+、Safari 11.1+、Edge 79+)では全て対応済み。2026年現在、IE11のサポートが不要なプロジェクトであれば積極的に使おう。
正規表現の落とし穴と注意点
正規表現は強力なツールだが、知らないと予期しない結果になる落とし穴がいくつかある。ここでは実務で特に遭遇しやすい4つの注意点を解説する。
1. 貪欲マッチ vs 非貪欲マッチ(.* vs .*?)
正規表現エンジンはデフォルトで「貪欲(greedy)」に動作し、できるだけ多くの文字にマッチしようとする。HTMLタグの取得で意図しない範囲までマッチしてしまうのはこれが原因だ。
対策
.* を使うときは「本当に全部マッチさせたいのか」を常に自問する。特にHTMLタグや引用符で囲まれた文字列を扱う場合は、.*?(非貪欲)か、[^<]*(特定文字以外)を使うほうが安全だ。
2. 日本語(マルチバイト)文字の扱い
JavaScript の正規表現でサロゲートペア(絵文字や一部の漢字)を扱う場合、u フラグを付けないと正しく動作しない。1文字として扱いたいのに2文字として認識されてしまう問題が起きる。
3. 改行文字の注意(\n vs \r\n)
改行コードはOS環境によって異なる。macOS/Linux は \n(LF)、Windows は \r\n(CRLF)が標準だ。ユーザーがテキストエリアに入力したデータや、CSVファイルの内容を処理するときにこの違いが問題になることがある。
4. パフォーマンス(バックトラッキング爆発)
正規表現エンジンはマッチに失敗すると別の経路を試みる「バックトラッキング」を行う。量指定子をネストさせると組み合わせが指数関数的に増大し、処理が極端に遅くなる「バックトラッキング爆発(Catastrophic Backtracking)」が起きる。
注意: ReDoS攻撃
バックトラッキング爆発はセキュリティ脆弱性にもなる。ユーザー入力を正規表現パターンに直接使う場合、悪意あるユーザーが意図的に処理を遅延させる「ReDoS(Regular Expression Denial of Service)」攻撃の標的になりうる。ユーザー入力をパターンに使う場合は必ずエスケープ処理を行い、タイムアウトを設けること。
Python・PHPでの使い方の違い
正規表現の基本構文は共通だが、各言語でのAPIや記法に差がある。特にPythonの match と search の違いは実務でよくハマるポイントなので注意したい。
Python
Pythonでは標準ライブラリの re モジュールを使う。r"pattern"(rawストリング)でバックスラッシュを書きやすくするのが慣例だ。同じパターンを複数回使う場合は re.compile() でコンパイルしておくとパフォーマンスが向上する。
PHP
PHPでは PCRE(Perl Compatible Regular Expressions)を使う preg_* 関数群が標準だ。パターンは /pattern/flags 形式でデリミタが必要な点に注意。JavaScriptに慣れた人が最初につまずきやすいポイントだ。
| 操作 | JavaScript | Python | PHP |
|---|---|---|---|
| マッチ確認 | regex.test(str) |
re.search(pat, str) |
preg_match(pat, str) |
| マッチ結果取得 | str.match(regex) |
re.findall(pat, str) |
preg_match_all(pat, str) |
| 置換 | str.replace(regex, rep) |
re.sub(pat, rep, str) |
preg_replace(pat, rep, str) |
| 分割 | str.split(regex) |
re.split(pat, str) |
preg_split(pat, str) |
正規表現テスターの活用
正規表現は書いてすぐ動くとは限らない。「動いているつもりが想定外のパターンにもマッチしていた」という経験をしたことがある人は少なくないはずだ。テスターを使ってパターンとテスト文字列を並べて確認する習慣が、バグを早期に発見する一番の近道になる。
-
パターンを入力
正規表現フィールドに試したいパターンを入力する。メタ文字の入力補助機能があるため、初心者でも迷わず使い始められる。
-
テスト文字列を貼り付け
マッチ確認したい文字列(メールアドレス一覧、ログデータなど)をテキストエリアに貼り付ける。ローカル処理なので、実際のログデータや個人情報が含まれていても安全だ。
-
マッチ結果をリアルタイム確認
マッチした部分がハイライト表示される。キャプチャグループの内容も個別に確認できる。
-
フラグを切り替えて動作確認
g(グローバル)、i(大文字小文字無視)、m(複数行)フラグをON/OFFして挙動の違いを把握する。フラグ1つで動作が変わることを体感しておくと、後の理解が速くなる。
ツールで効率化
当サイトの正規表現テスターはブラウザ上で完全動作する。入力したデータがサーバーに送信されないため、ログや個人情報を含むデータでも安心して使える。
パフォーマンスの注意点
正規表現は便利だが、書き方を誤ると極端に遅くなる「バックトラッキング爆発(Catastrophic Backtracking)」という問題が発生する。本番環境でユーザー入力を処理する場合は特に意識が必要だ。
パフォーマンス改善のポイント
- 量指定子のネスト(
(a+)+のような形)を避ける - あいまいな代替(
(a|aa)+)を避け、より具体的なパターンにする - 同じ正規表現を何度も使う場合はコンパイル・キャッシュする(Pythonの
re.compile()など) - 可能なら先頭アンカー(
^)を使い、マッチ探索範囲を限定する - 非常に長い文字列に対してはストリーム処理を検討する
- 不要なキャプチャグループは
(?:...)(非キャプチャ)に変更する - ユーザー入力をパターンに使う場合は特殊文字をエスケープし、タイムアウトを設ける