正規表現(Regular Expression、regex)は、テキストのパターンマッチングを行うための強力なツールです。ログの解析、入力値のバリデーション、テキストの検索・置換など、あらゆる場面で活用できます。しかし、複雑な記号の羅列に見えるため、苦手意識を持つエンジニアも多いのではないでしょうか。
本記事では、正規表現の基礎文法から、実務で即使えるパターン集、パフォーマンスの注意点、各言語での使い方まで実践的に解説します。
正規表現の基礎文法
正規表現を使いこなすための基本要素を確認しましょう。これらを組み合わせることで、複雑なパターンも表現できます。
文字クラスとメタ文字
基本的なメタ文字
.(ドット)は改行以外の任意の1文字にマッチします。^は行頭、$は行末を示します。\はメタ文字のエスケープに使います。
文字クラス
[abc]はa、b、cのいずれかにマッチします。[a-z]はaからzまでの小文字にマッチし、[0-9]は数字にマッチします。[^abc]はa、b、c以外の文字にマッチします(否定)。
定義済み文字クラス
\dは数字([0-9]と同等)、\Dは数字以外、\wは英数字とアンダースコア([a-zA-Z0-9_]と同等)、\Wはそれ以外、\sは空白文字(スペース、タブ、改行など)、\Sは空白以外にマッチします。
量指定子(Quantifiers)
直前のパターンの繰り返し回数を指定します。
*は0回以上の繰り返し、+は1回以上の繰り返し、?は0回または1回(省略可能)にマッチします。
{n}はちょうどn回、{n,}はn回以上、{n,m}はn回以上m回以下の繰り返しを指定します。
貪欲マッチと最短マッチ
デフォルトでは量指定子は「貪欲(greedy)」で、できるだけ長い文字列にマッチしようとします。量指定子の後に?を付けると「最短(lazy)」マッチになり、できるだけ短い文字列にマッチします。
たとえば、<.+>は<p>text</p>全体にマッチしますが、<.+?>は<p>だけにマッチします。HTMLタグの抽出などで頻繁に使う区別です。
グループとキャプチャ
(pattern)でグループ化し、マッチした部分をキャプチャ(抽出)できます。キャプチャした内容は\1、\2のように後方参照で再利用できます。
(?:pattern)はグループ化のみ行い、キャプチャしません(非キャプチャグループ)。パフォーマンスが若干向上し、キャプチャの番号が不要な場合に使います。
(?<name>pattern)は名前付きキャプチャグループで、番号ではなく名前でキャプチャ内容にアクセスできます。可読性が大幅に向上するため、複雑な正規表現では積極的に使いましょう。
アンカーと先読み・後読み
位置にマッチする高度なパターンを理解しましょう。
アンカー
\bは単語境界(word boundary)にマッチします。\bcat\bは「cat」にはマッチしますが、「category」の中の「cat」にはマッチしません。テキスト検索で特に重要な機能です。
先読みと後読み(Lookahead/Lookbehind)
先読みと後読みは、パターンの前後に特定の条件を付けるためのアサーションです。マッチ結果には含まれません(ゼロ幅アサーション)。
肯定先読み (?=pattern)
後にpatternが続く位置にマッチします。\d+(?=円)は「500円」の「500」にマッチしますが、「500ドル」にはマッチしません。
否定先読み (?!pattern)
後にpatternが続かない位置にマッチします。\d+(?!円)は「500ドル」の「500」にマッチします。
肯定後読み (?<=pattern)
前にpatternがある位置にマッチします。(?<=\$)\d+は「$100」の「100」にマッチします。
否定後読み (?<!pattern)
前にpatternがない位置にマッチします。特定の接頭辞を除外する場合に使います。
先読みと後読みは、パスワードの複雑性チェック(大文字・小文字・数字をすべて含むか)や、特定の文脈でのパターン抽出に活用できます。
実践パターン集:バリデーション
Webアプリケーションの入力バリデーションで使える正規表現パターンを紹介します。
メールアドレス
完全にRFC 5322に準拠したメールアドレスの正規表現は非常に複雑になるため、実用的な範囲で検証するパターンを使います。
^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$
ローカルパート(@の前)に英数字と一部の記号を許可し、ドメインパートに英数字とハイフン、トップレベルドメインに2文字以上の英字を要求します。実際のバリデーションでは、この正規表現で基本的な形式を確認した上で、確認メールの送信で到達性を検証するのが推奨されます。
電話番号(日本)
^0\d{1,4}[\-]?\d{1,4}[\-]?\d{4}$
0から始まる日本の電話番号にマッチします。ハイフンの有無に対応しています。携帯電話の番号に限定する場合は^0[789]0[\-]?\d{4}[\-]?\d{4}$とします。
URL
^https?:\/\/[\w\-]+(\.[\w\-]+)+[\/\w\-._~:?#\[\]@!$&'()*+,;=]*$
http/httpsで始まるURLにマッチします。クエリパラメータやフラグメントも含む基本的なURL構造を検証できます。
パスワード強度チェック
先読みを活用して、パスワードの複雑性を検証します。
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$
小文字・大文字・数字・特殊文字をそれぞれ1文字以上含み、8文字以上であることを検証します。各(?=.*pattern)が先読みとして機能し、順序に関係なく各条件をチェックします。
郵便番号(日本)
^\d{3}[\-]?\d{4}$
ハイフンありなしの両方に対応します。
実践パターン集:テキスト処理
ログ解析やテキストの加工で使えるパターンを紹介します。
ログ解析
Apacheアクセスログの解析
^(\S+) \S+ \S+ \[([^\]]+)\] "(\S+) (\S+) \S+" (\d{3}) (\d+|-)
IPアドレス、日時、HTTPメソッド、リクエストパス、ステータスコード、レスポンスサイズをキャプチャします。名前付きキャプチャを使うとさらに可読性が上がります。
日時パターンの抽出
\d{4}[\-/]\d{2}[\-/]\d{2}[\sT]\d{2}:\d{2}:\d{2}
ISO 8601風の日時フォーマット(2026-03-27 12:34:56やT区切り)にマッチします。
テキストの置換
キャメルケースをスネークケースに変換
検索パターン:([a-z])([A-Z])
置換パターン:$1_$2(その後に小文字化)
「userName」を「user_Name」に変換し、さらに小文字化して「user_name」にします。
HTMLタグの除去
<[^>]+>
HTMLタグを除去してプレーンテキストを抽出する基本パターンです。ただし、正規表現でのHTML解析には限界があるため、本格的な処理にはHTMLパーサーを使うべきです。
行末の空白除去
[ \t]+$(多くのエディタで対応)
行末の不要なスペースやタブを検出・除去します。
データ抽出
CSV内の引用符付きフィールド
"([^"]*(?:""[^"]*)*)"
ダブルクォートで囲まれたCSVフィールドにマッチします。フィールド内にエスケープされたダブルクォート("")が含まれる場合にも対応します。
IPアドレスの抽出
\b(?:\d{1,3}\.){3}\d{1,3}\b
テキスト中からIPv4アドレスを抽出します。厳密な範囲チェック(各オクテットが0-255)を加えたい場合は、より複雑なパターンが必要です。
各プログラミング言語での正規表現
正規表現の文法は言語間でほぼ共通ですが、APIの使い方やフラグの指定方法に違いがあります。
JavaScript
JavaScriptでは、正規表現リテラル/pattern/flagsまたはRegExpコンストラクタで正規表現を作成します。主要なメソッドはtest()(マッチするかの判定)、match()(マッチ結果の取得)、replace()(置換)です。
フラグとして、g(グローバル検索)、i(大文字小文字を区別しない)、m(複数行モード)、s(.が改行にもマッチ)、u(Unicode対応)があります。
ES2018以降では、名前付きキャプチャグループ(?<name>pattern)と後読みアサーションがサポートされています。
Python
Pythonのreモジュールで正規表現を使います。re.compile()でパターンをコンパイルし、search()(最初のマッチ)、findall()(すべてのマッチ)、sub()(置換)を使います。
Pythonでは生文字列r"pattern"を使うことで、バックスラッシュのエスケープが不要になります。re.VERBOSEフラグを使うと、パターン内にコメントや空白を含められるため、複雑な正規表現の可読性を向上できます。
Go
GoのregexpパッケージはRE2構文を採用しています。後方参照と先読み/後読みはサポートされていません(ReDoS攻撃の防止のため)。regexp.MustCompile()でコンパイルし、FindString()、FindAllString()、ReplaceAllString()などを使います。
パフォーマンスの注意点
正規表現のパフォーマンスは、パターンの書き方によって大きく変わります。
ReDoS(正規表現サービス拒否攻撃)
悪意のある入力によって正規表現の処理が指数関数的に遅くなるReDoS攻撃に注意が必要です。バックトラッキングが爆発的に増加するパターン(たとえば(a+)+$に対して「aaaaaaaab」を入力)が原因です。
対策
ネストした量指定子((a+)+)を避けること、入力文字列の長さを制限すること、タイムアウトを設定すること(言語によってはサポートされています)、可能であればRE2互換の正規表現エンジンを使うことが対策になります。
パフォーマンス改善のTips
コンパイル済みパターンの再利用
ループ内で毎回正規表現をコンパイルするのは無駄です。ループの外でコンパイルし、結果を再利用しましょう。
非キャプチャグループの使用
キャプチャが不要なグループには(?:...)を使います。キャプチャのオーバーヘッドを削減できます。
アンカーの活用
^や$でパターンの位置を限定することで、検索範囲を絞り込みパフォーマンスを向上させます。
具体的な文字の指定
.*のような曖昧なパターンよりも、[^"]*のように具体的な文字クラスを指定する方が、バックトラッキングが減少し高速になります。
正規表現をデバッグする方法
複雑な正規表現のデバッグは、適切なツールを使うことで効率化できます。
オンラインテストツール
regex101(https://regex101.com)
正規表現のテストと解析に最も人気のあるツールです。パターンの各部分の意味を日本語で説明してくれる機能、マッチの過程を視覚的に表示するデバッガー機能、各言語(Python、JavaScript、Go、PHP、Java)のコード生成機能があります。
RegExr(https://regexr.com)
直感的なUIでパターンを構築・テストできます。チートシートが充実しており、学習にも適しています。
段階的なパターン構築
複雑な正規表現を一度に書こうとせず、段階的に構築しましょう。まずは最もシンプルなパターンから始め、条件を1つずつ追加しながらテストします。
各部分の意味をコメントとして記録しておくと、後から見た時の理解が容易になります。Pythonのre.VERBOSEやJavaScriptの変数分割など、言語の機能を活用してパターンを分割・コメント化しましょう。
まとめ
正規表現は、テキスト処理の万能ツールです。基本的なメタ文字・量指定子・文字クラスを理解し、先読み/後読みやキャプチャグループを組み合わせることで、複雑なパターンマッチングが実現できます。
バリデーション、ログ解析、テキスト置換、データ抽出など、実務での用途は多岐にわたります。本記事で紹介したパターンを自分のプロジェクトに合わせてカスタマイズし、regex101などのツールで動作を確認しながら使ってみてください。
正規表現を書く際は、ReDoSのリスクに注意し、可読性とパフォーマンスのバランスを意識しましょう。複雑すぎるパターンは分割や名前付きキャプチャで整理し、チームメンバーが理解できるレベルを保つことが、保守しやすいコードにつながります。
関連記事
AIエージェント開発入門|自律型AIの仕組みと構築方法を解説【2026年版】
AI駆動コーディングワークフロー|Claude Code・Cursor・Copilotの実践的使い分け
プロンプトエンジニアリング上級編|Chain-of-Thought・Few-Shot・ReActの実践
APIレート制限の設計と実装|トークンバケット・スライディングウィンドウ解説
APIバージョニング戦略|URL・ヘッダー・クエリパラメータの使い分け
BIツール入門|Metabase・Redash・Looker Studioでデータ可視化する方法
チャットボット開発入門|LINE Bot・Slack Botの構築方法と活用事例
CI/CDパイプラインの基礎|継続的インテグレーション・デリバリーの全体像