正規表現の実践ガイド|検索・置換・バリデーションで使えるパターン集

kento_morota 12分で読めます

正規表現(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のリスクに注意し、可読性とパフォーマンスのバランスを意識しましょう。複雑すぎるパターンは分割や名前付きキャプチャで整理し、チームメンバーが理解できるレベルを保つことが、保守しやすいコードにつながります。

#正規表現#regex#プログラミング
共有:
無料メルマガ

週1回、最新の技術記事をお届け

AI・クラウド・開発の最新記事を毎週月曜にメールでお届けします。登録は無料、いつでも解除できます。

プライバシーポリシーに基づき管理します

起業準備に役立つ情報、もっとありますよ。

まずは話だけ聞いてもらう