正規表現:初心者向けガイド
· 12分で読めます
📑 目次
正規表現(regex)は、開発者のツールキットの中で最も強力なツールの一つです。最初は威圧的に見えるかもしれませんが、基本を理解すれば、テキスト処理、検証、データ抽出に欠かせないものになります。
ユーザー入力の検証、ログファイルの解析、データの変換など、正規表現はテキストパターンを扱うための簡潔で柔軟な方法を提供します。このガイドでは、完全な初心者から自信を持って正規表現を使えるユーザーへと導きます。
正規表現とは?
正規表現は、検索パターンを定義する文字列です。テキストパターンを記述するためのミニ言語と考えてください。正確な文字列を検索する代わりに、「任意のメールアドレス」や「任意の電話番号」のようなパターンを検索できます。
正規表現は、事実上すべてのプログラミング言語とテキストエディタで使用されています。JavaScript、Python、Java、PHP、Ruby、Go、その他無数の言語でサポートされています。grep、sed、awkなどのコマンドラインツールでさえ、正規表現に大きく依存しています。
正規表現の素晴らしさは、構文を一度学べば、さまざまなツールや言語に適用できることです。正規表現の「フレーバー」(PCRE、JavaScript、Pythonなど)間には若干の違いがありますが、核となる概念は同じです。
プロのヒント: シンプルなパターンから始めて、徐々に複雑さを増していきましょう。最初の試みで完璧な正規表現を書こうとしないでください。テストしながら反復して洗練させていきます。
基本的な構成要素
すべての正規表現パターンは、基本的なコンポーネントから構築されています。より複雑なパターンに進む前に、これらの構成要素を理解することが不可欠です。
リテラル文字
最もシンプルな正規表現は、単なるプレーンテキストです。パターンcatは、文字列内のどこでも正確なテキスト「cat」にマッチします。ほとんどの英数字は、それ自体に文字通りマッチします。
ただし、一部の文字は正規表現で特別な意味を持ち、バックスラッシュでエスケープする必要があります:. ^ $ * + ? { } [ ] \ | ( )
リテラルのピリオドにマッチさせるには、単に.ではなく\.と書きます。
ドットメタ文字
ドット(.)は、改行以外の任意の1文字にマッチするワイルドカードです。パターンc.tは、「cat」、「cot」、「cut」、「c9t」、さらには「c@t」にもマッチします。
これにより、ドットは非常に強力になりますが、不注意に使用すると潜在的に危険でもあります。後でより具体的にする方法について説明します。
文字クラス
角括弧は文字クラスを作成し、括弧内の任意の1文字にマッチします:
[aeiou]は任意の母音にマッチ[0-9]は任意の数字にマッチ[a-zA-Z]は任意の文字(大文字または小文字)にマッチ[a-z0-9]は任意の小文字または数字にマッチ
キャレットを使って文字クラスを否定することもできます:[^0-9]は数字ではない任意の文字にマッチします。
量指定子の説明
量指定子は、パターンが何回マッチすべきかを指定します。繰り返したい要素の後に配置されます。
| 量指定子 | 意味 | 例 |
|---|---|---|
* |
0回以上 | ab*cは「ac」、「abc」、「abbc」にマッチ |
+ |
1回以上 | ab+cは「abc」、「abbc」にマッチするが「ac」にはマッチしない |
? |
0回または1回(オプション) | colou?rは「color」と「colour」にマッチ |
{n} |
正確にn回 | \d{3}は正確に3桁の数字にマッチ |
{n,} |
n回以上 | \d{2,}は2桁以上の数字にマッチ |
{n,m} |
n回からm回の間 | \d{2,4}は2、3、または4桁の数字にマッチ |
貪欲マッチと怠惰マッチ
デフォルトでは、量指定子は貪欲です。つまり、できるだけ多くのテキストにマッチします。パターン.*は、可能な限りすべてを消費します。
HTMLタグのマッチを考えてみましょう:<.+>を<b>bold</b>に適用すると、<b>だけでなく、文字列全体にマッチします。
量指定子を怠惰(できるだけ少なくマッチ)にするには、疑問符を追加します:<.+?>は、<b>と</b>を別々にマッチさせます。
クイックヒント: 迷ったら、怠惰な量指定子を使用してください。より予測可能で、予期しないマッチを引き起こす可能性が低くなります。
文字クラスとショートカット
[0-9]を繰り返し書くのは面倒です。正規表現は、一般的なパターンのための短縮文字クラスを提供します。
| 短縮形 | 同等 | 説明 |
|---|---|---|
\d |
[0-9] |
任意の数字 |
\D |
[^0-9] |
任意の非数字 |
\w |
[a-zA-Z0-9_] |
任意の単語文字 |
\W |
[^a-zA-Z0-9_] |
任意の非単語文字 |
\s |
[ \t\r\n\f] |
任意の空白文字 |
\S |
[^ \t\r\n\f] |
任意の非空白文字 |
パターンに注目してください:大文字バージョンは、小文字バージョンの否定です。これにより、正規表現がより読みやすく簡潔になります。
ショートカットを使った実践的な例
\d{3}-\d{4}は「555-1234」のような電話番号にマッチ\w+@\w+\.\w+はシンプルなメールアドレスにマッチ\s+は1つ以上の空白文字にマッチ\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}はIPアドレスにマッチ(完璧ではありませんが)
アンカーと境界
アンカーは文字にマッチしません。テキスト内の位置にマッチします。正確なパターンマッチングには不可欠です。
行アンカー
^は行の先頭にマッチ$は行の末尾にマッチ
パターン^Helloは、行の先頭にある「Hello」にのみマッチします。同様に、world$は行の末尾にある「world」にのみマッチします。
行全体を正確にマッチさせるには、両方を使用します:^Hello world$は、前後に何もない「Hello world」だけを含む行にのみマッチします。
単語境界
\bアンカーは単語境界にマッチします。単語文字(\w)と非単語文字の間の位置です。
これは単語全体をマッチさせるのに非常に便利です。パターン\bcat\bは「cat」にマッチしますが、「category」や「scat」にはマッチしません。
単語境界がなければ、catは3つすべてにマッチします。単語境界は、複雑さを追加することなく、パターンをより正確にします。
プロのヒント: 単語全体を検索するときは、常に単語境界を使用してください。誤ったマッチを防ぎ、正規表現をより信頼性の高いものにします。
グループとキャプチャ
括弧は正規表現で2つの目的を果たします:グループ化とキャプチャです。仕組みを理解すれば、最も強力な機能の1つです。
量指定子のためのグループ化
括弧を使用すると、複数の文字に量指定子を適用できます。パターン(ha)+は「ha」、「haha」、「hahaha」などにマッチします。
括弧がなければ、ha+は「ha」、「haa」、「haaa」にマッチします。量指定子は直前の文字にのみ適用されます。
キャプチャグループ
グループは、後で使用するためにマッチしたテキストもキャプチャします。この電話番号パターンを考えてみましょう:(\d{3})-(\d{3})-(\d{4})
これにより、市外局番、プレフィックス、回線番号の3つのキャプチャグループが作成されます。ほとんどの言語で、これらのキャプチャにアクセスできます:
- JavaScript:
match[1]、match[2]、match[3] - Python:
match.group(1)、match.group(2)、match.group(3) - 置換では:
$1、$2、$3または\1、\2、\3
非キャプチャグループ
キャプチャせずにグループ化したい場合があります。非キャプチャグループには(?:...)を使用します:(?:https?://)?www\.example\.com
これによりプロトコルがグループ化されますが、キャプチャグループは作成されません。これによりパフォーマンスが向上し、コードが簡素化されます。
名前付きキャプチャグループ
番号付きグループの代わりに、明確にするために名前を付けることができます:(?<area>\d{3})-(?<prefix>\d{3})-(?<line>\d{4})
Pythonではmatch.group('area')、JavaScriptではmatch.groups.areaで名前付きグループにアクセスします。これによりコードが自己文書化されます。
実践的な例
学んだことを実際のシナリオに適用しましょう。これらのパターンは出発点です。特定の要件に合わせて調整する必要があることがよくあります。
メール検証
シンプルなメールパターン:[\w.+-]+@[\w.-]+\.[a-zA-Z]{2,}
これは最も一般的なメール形式にマッチしますが、RFC準拠ではありません。本番環境では、専用のメール検証ライブラリの使用を検討してください。メールの正規表現は非常に複雑になる可能性があります。
URLマッチング
HTTPおよびHTTPS URLにマッチ:https?://[\w.-]+(?:\.[\w.-]+)+(?:/[\w./?&=%-]*)?
これはドメイン、パス、クエリ文字列を処理します。s?により、「https」の「s」がオプションになります。
電話番号
柔軟な形式の米国電話番号:\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}
これは次のような形式にマッチします:
- (555) 123-4567
- 555-123-4567
- 555.123.4567
- 5551234567
日付形式
ISO日付形式(YYYY-MM-DD):\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])
これにより、月が01-12、日が01-31であることが保証されます。2024-99-99のような無効な日付を受け入れる\d{4}-\d{2}-\d{2}よりも正確です。
IPアドレス
IPv4アドレス:\b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b
これにより、各オクテットが0-255の間であることが検証され、999.999.999.999のようなマッチが防止されます。
クレジットカード番号
オプションのスペースまたはダッシュ付きのクレジットカード番号にマッチ:\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}
Luhnアルゴリズムを使用してチェックサムを別途検証することを忘れないでください。正規表現だけではカード番号が有効かどうかを確認できません。
セキュリティ注意: クレジットカード番号をプレーンテキストでログに記録したり保存したりしないでください。これらのパターンは初期形式検証にのみ使用し、その後すぐに機密データをトークン化してください。
ログからのデータ抽出
Apacheログエントリを解析: