正規表現:初心者向けガイド
· 12分で読めます
目次
正規表現とは?
正規表現は、一般的にregexまたはregexpと略され、検索パターンを定義する文字列です。これらの強力なツールは、テキストデータ内での文字列マッチング、検証、操作に広く使用されています。正規表現をマスターすることで、テキスト検証、データ抽出、データフォーマットなどのタスクを驚くほど効率的に自動化できます。
一見すると、正規表現はその密集した暗号的な構文のため威圧的に見えるかもしれません。しかし、その核となる要素を理解することで、そうでなければ何百行もの手続き型コードを必要とする高度なデータ処理技術への扉が開かれます。正規表現は、パターンマッチング専用に設計された特殊なミニ言語と考えてください。
正規表現は、ソフトウェア開発、データ分析、システム管理、コンテンツ管理、ウェブスクレイピングなど、数多くの実世界のシナリオで遭遇します。一般的な使用例には、ログ解析、フォーム検証、CSVファイルのデータ変換、検索と置換操作、非構造化テキストからの構造化情報の抽出などがあります。
プロのヒント:正規表現は、JavaScript、Python、Java、PHP、Ruby、Goを含むほぼすべての最新のプログラミング言語でサポートされています。また、VS Code、Sublime Textなどのテキストエディタや、grepやsedなどのコマンドラインツールにも組み込まれています。
正規表現の構文を理解する
正規表現の構文は、強力なパターンマッチング機能を作成するために組み合わされる基礎的な要素の上に構築されています。表記法は最初は暗号的に見えるかもしれませんが、各記号はパターンにマッチすべきテキストを定義する上で特定の目的を果たします。
すべての正規表現パターンの基礎を形成する本質的な構成要素を分解してみましょう。これらの核となる要素を理解することで、事実上あらゆるテキストマッチングシナリオのパターンを構築できるようになります。
基本的なメタ文字
メタ文字は、正規表現において文字通りにマッチするのではなく特定の意味を持つ特殊文字です。最も基本的なものは次のとおりです:
.(ドット):改行以外の任意の1文字にマッチします。例えば、a.cは「abc」、「a2c」、「a@c」にマッチしますが、「ac」にはマッチしません。\(バックスラッシュ):特殊文字をエスケープして文字通りにマッチさせます。実際のピリオドにマッチさせるには\.を使用します。|(パイプ):OR演算子として機能します。パターンcat|dogは「cat」または「dog」のいずれかにマッチします。
メタ文字を文字通りにマッチさせる必要がある場合(実際のアスタリスクやピリオドを検索する場合など)、バックスラッシュでエスケープする必要があります。例えば、\*は文字通りのアスタリスク文字にマッチします。
クイックヒント:当社の正規表現マッチテスターを使用して、パターンをリアルタイムで試し、正規表現が何にマッチするかを正確に確認してください。
文字クラスと範囲
文字クラスを使用すると、特定のセットから任意の1文字にマッチさせることができます。角括弧で囲まれ、単一の位置で複数の可能な文字を指定する簡潔な方法を提供します。
基本的な文字クラス
[abc]:「a」、「b」、または「c」のいずれかの1文字にマッチします。[^abc]:「a」、「b」、または「c」以外の任意の文字にマッチします。括弧内のキャレットはクラスを否定します。[a-z]:「a」から「z」までの任意の小文字にマッチします。[A-Z]:任意の大文字にマッチします。[0-9]:0から9までの任意の数字にマッチします。[a-zA-Z0-9]:任意の英数字にマッチします。
単一の文字クラス内で複数の範囲を組み合わせることができます。例えば、[a-zA-Z0-9_]は任意の文字、数字、またはアンダースコアにマッチします—ユーザー名や変数名の検証によく使用されます。
定義済み文字クラス
ほとんどの正規表現エンジンは、一般的なパターンのための短縮文字クラスを提供しています:
| 短縮形 | 同等 | 説明 |
|---|---|---|
\d |
[0-9] |
任意の数字 |
\D |
[^0-9] |
任意の非数字 |
\w |
[a-zA-Z0-9_] |
任意の単語文字 |
\W |
[^a-zA-Z0-9_] |
任意の非単語文字 |
\s |
[ \t\n\r\f\v] |
任意の空白文字 |
\S |
[^ \t\n\r\f\v] |
任意の非空白文字 |
これらの短縮クラスは、パターンをより読みやすく、保守しやすくします。例えば、\d{3}-\d{3}-\d{4}は、電話番号にマッチさせるための[0-9]{3}-[0-9]{3}-[0-9]{4}よりもはるかに明確です。
量指定子の説明
量指定子は、パターン内で要素が何回出現すべきかを指定します。修飾する要素の後に配置され、可変長パターンのマッチングに不可欠です。
基本的な量指定子
*:0回以上の出現にマッチします。パターンab*cは「ac」、「abc」、「abbc」、「abbbc」などにマッチします。+:1回以上の出現にマッチします。パターンab+cは「abc」、「abbc」にマッチしますが、「ac」にはマッチしません。?:0回または1回の出現にマッチします(前の要素をオプションにします)。パターンcolou?rは「color」と「colour」の両方にマッチします。
特定の量指定子
繰り返し回数を正確に制御するには、中括弧を使用します:
{n}:正確にn回の出現にマッチします。\d{4}は正確に4桁の数字にマッチします。{n,}:n回以上の出現にマッチします。\d{3,}は3桁以上の数字にマッチします。{n,m}:n回からm回(両端を含む)の出現にマッチします。\d{2,4}は2、3、または4桁の数字にマッチします。
貪欲な量指定子と怠惰な量指定子
デフォルトでは、量指定子は「貪欲」です—できるだけ多くのテキストにマッチします。量指定子の後に疑問符を追加すると「怠惰」または「非貪欲」になり、できるだけ少ないテキストにマッチします。
文字列"<div>content</div>"を考えてみましょう:
<.+>(貪欲)は最初の<から最後の>まで文字列全体にマッチします<.+?>(怠惰)は<div>のみにマッチし、次に</div>に別々にマッチします
プロのヒント:怠惰な量指定子は、HTML、XML、またはネストされた構造を解析する際に重要です。区切り文字間で多すぎるコンテンツにマッチするのを防ぎます。
アンカーと境界
アンカーは文字にマッチしません—テキスト内の位置にマッチします。文字列内のどこでもではなく、特定の場所でパターンがマッチすることを保証するために不可欠です。
位置アンカー
^:行または文字列の先頭にマッチします。^Helloは先頭の「Hello」のみにマッチします。$:行または文字列の末尾にマッチします。world$は末尾の「world」のみにマッチします。\A:文字列の絶対的な先頭にマッチします(複数行モードの影響を受けません)。\Z:文字列の絶対的な末尾にマッチします(複数行モードの影響を受けません)。
先頭と末尾のアンカーを組み合わせることで、文字列全体がパターンにマッチすることを保証します。例えば、^\d{5}$は正確に5桁の数字を含み、それ以外は何も含まない文字列にマッチします—米国の郵便番号の検証に最適です。
単語境界
単語境界は、より大きな単語の一部に誤ってマッチすることなく、完全な単語にマッチさせるのに非常に便利です:
\b:単語境界(単語文字と非単語文字の間の位置)にマッチします。\B:非単語境界にマッチします。
パターン\bcat\bは独立した単語としての「cat」にマッチしますが、「category」や「concatenate」の中の「cat」にはマッチしません。これは、特定の単語をターゲットにしたい検索と置換操作に不可欠です。
グループとキャプチャ
グループを使用すると、複数の文字を単一のユニットとして扱い、後で使用するためにマッチしたテキストをキャプチャできます。データの抽出や複雑なパターンの作成に基本的です。
キャプチャグループ
括弧はマッチしたテキストを記憶するキャプチャグループを作成します:
(\d{3})-(\d{3})-(\d{4})
このパターンは電話番号にマッチし、3つのグループをキャプチャします:市外局番、プレフィックス、回線番号。これらのキャプチャされたグループは、置換文字列で参照したり、プログラムで抽出したりできます。
ほとんどのプログラミング言語では、キャプチャされたグループは1から始まる番号が付けられます。グループ0は常に完全なマッチを参照します。例えば、JavaScriptでは:
const regex = /(\d{3})-(\d{3})-(\d{4})/;
const match = "555-123-4567".match(regex);
// match[0] = "555-123-4567" (完全なマッチ)
// match[1] = "555" (最初のグループ)
// match[2] = "123" (2番目のグループ)
// match[3] = "4567" (3番目のグループ)
非キャプチャグループ
量指定子や選択を適用するためにグループ化が必要だが、マッチしたテキストをキャプチャする必要がない場合があります。非キャプチャグループには(?:...)を使用します:
(?:https?|ftp)://[^\s]+
これは、http、https、またはftpで始まるURLにマッチしますが、プロトコル用の個別のキャプチャグループは作成しません。非キャプチャグループはパフォーマンスを向上させ、キャプチャグループの番号付けをクリーンに保ちます。
名前付きキャプチャグループ
名前付きグループは、キャプチャされたテキストに意味のある名前を割り当てることで、正規表現をより読みやすく保守しやすくします:
(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})
グループ1が年であることを覚える代わりに、名前で参照できます。構文は正規表現エンジン間でわずかに異なりますが、ほとんどの最新の実装は名前付きグループをサポートしています。
高度な正規表現テクニック
基本をマスターしたら、これらの高度なテクニックは複雑なパターンマッチングの課題に取り組むのに役立ちます。
先読みと後読みアサーション
先読み・後読みアサーションは、現在の位置の前後にパターンが存在するかどうかをチェックしますが、マッチに含めません:
| アサーション | 構文 | 説明 |
|---|---|---|
| 肯定先読み | (?=...) |
パターンが後に続く場合にマッチ |
| 否定先読み | (?!...) |
パターンが後に続かない場合にマッチ |
| 肯定後読み | (?<=...) |
パターンが前にある場合にマッチ |
| 否定後読み | (?<!...) |
パターンが前にない場合にマッチ |
例:\d+(?= dollars)は「 dollars」が後に続く数字にマッチしますが、「 dollars」はマッチに含まれません。これは、特定のコンテキストに現れる値を抽出したい場合に便利です。
後方参照
後方参照を使用すると、グループによって以前にキャプチャされたのと同じテキストにマッチさせることができます。バックスラッシュ表記で番号が付けられます:
\b(\w+)\s+\1\b
このパターンは「the the」や「is is」のような繰り返された単語にマッチします。\1は最初のグループによってキャプチャされたものを参照し、両方の単語が同一であることを保証します。
条件付きパターン
一部の正規表現エンジンは、前のグループがマッチしたかどうかに基づいて異なる選択肢にマッチする条件付きパターンをサポートしています:
(a)?b(?(1)c|d)
これは、オプションの「a」が存在する場合は「abc」に、存在しない場合は「bd」にマッチします。条件付きパターンは強力ですが、正規表現を読みにくくする可能性があるため、慎重に使用してください。
プロのヒント:先読み・後読みや条件などの高度な機能は、すべての正規表現エンジンでサポートされているわけではありません。互換性については、常にプログラミング言語またはツールのドキュメントを確認してください。
実用的な応用
正規表現が輝く実世界のシナリオを、すぐに使用できる実用的な例とともに探ってみましょう。
メール検証
完璧なメール検証は驚くほど複