例 |
正規表現の例 |
数値範囲 |
浮動小数点数 |
メールアドレス |
IPアドレス |
有効な日付 |
数値日付をテキストに変換 |
クレジットカード番号 |
完全な行のマッチング |
重複行の削除 |
プログラミング |
近くにある2つの単語 |
落とし穴 |
壊滅的なバックトラッキング |
過剰な繰り返し |
サービス拒否 |
すべてをオプションにする |
繰り返しキャプチャグループ |
Unicodeと8ビットの混合 |
このサイトのその他の情報 |
はじめに |
正規表現クイックスタート |
正規表現チュートリアル |
置換文字列チュートリアル |
アプリケーションと言語 |
正規表現の例 |
正規表現リファレンス |
置換文字列リファレンス |
書籍レビュー |
印刷可能なPDF |
このサイトについて |
RSSフィードとブログ |
マッチしたテキストの一部を掴むためにキャプチャグループが必要な正規表現を作成する際、よくある間違いは、繰り返されるグループをキャプチャするのではなく、キャプチャグループを繰り返すことです。違いは、繰り返されるキャプチャグループは最後の反復のみをキャプチャするのに対し、繰り返される別のグループをキャプチャするグループはすべての反復をキャプチャすることです。例を挙げれば、この違いが明確になります。
例えば、次のようなタグにマッチさせたいとしましょう。!abc!または!123!。この2つだけが可能性があり、どのタグが得られたのかを知るためにabcまたは123をキャプチャしたいとします。それは簡単です。!(abc|123)!でうまくいきます。
では、タグにabcと123の複数のシーケンスを含めることができるとしましょう。例えば、!abc123!または!123abcabc!。手っ取り早い解決策は!(abc|123)+!です。この正規表現は確かにこれらのタグにマッチします。しかし、タグのラベルをキャプチャグループにキャプチャするという要件は満たさなくなりました。この正規表現が!abc123!にマッチするとき、キャプチャグループは123のみを格納します。次に!123abcabc!にマッチするときは、abc.
のみを格納します。これは、正規表現エンジンが!(abc|123)+!を!abc123!にどのように適用するかを見ると簡単に理解できます。まず、!が!にマッチします。次に、エンジンはキャプチャグループに入ります。エンジンが対象文字列の最初の文字と2番目の文字の間の位置に到達したときに、キャプチャグループ#1に入ったことを記録します。グループ内の最初のトークンはabcで、これはabcにマッチします。マッチが見つかったため、2番目の代替案は試行されません(エンジンはバックトラッキングの位置を格納しますが、この例では使用されません)。エンジンはキャプチャグループから出ます。エンジンが文字列の4番目と5番目の文字の間の位置に到達したときに、キャプチャグループ#1が終了したことを記録します。
グループから出た後、エンジンはプラスに気づきます。プラスは貪欲なので、グループが再度試行されます。エンジンは再びグループに入り、文字列の4番目と5番目の文字の間でキャプチャグループ#1が入力されたことを記録します。また、プラスが強欲ではないため、バックトラックされる可能性があることも記録します。つまり、グループが2回目にマッチできない場合は問題ありません。このバックトラッキングノートでは、正規表現エンジンはグループの前の反復中のグループの入り口と出口の位置も保存します。
abcは123にマッチしませんが、123は成功します。グループが再び終了します。7番目と8番目の文字の間の出口位置が格納されます。
プラスは別の反復を許可するため、エンジンは再度試行します。バックトラッキング情報が格納され、グループの新しい入り口位置が保存されます。しかし、今度はabcと123の両方が!にマッチできません。グループが失敗し、エンジンがバックトラックします。バックトラッキング中に、エンジンはグループのキャプチャ位置を復元します。つまり、グループは4番目と5番目の文字の間に入力され、7番目と8番目の文字の間に出力されました。
エンジンは!で、これは!を続行します。全体的なマッチが見つかります。全体的なマッチは、対象文字列全体に及びます。キャプチャグループは文字5、6、7、つまり123を囲みます。マッチが見つかるとバックトラッキング情報は破棄されるため、グループが以前にabcにマッチする反復を持っていたことを後から知る方法はありません。(これに対する唯一の例外は、マッチ試行後もキャプチャグループのバックトラッキング情報を保持する.NET正規表現エンジンです。)
この例でのabc123をキャプチャする解決策は、もう明らかでしょう。正規表現エンジンは、グループに1回だけ出入りする必要があります。これは、プラスがキャプチャグループの外側ではなく内側にある必要があることを意味します。2つの選択肢をグループ化する必要があるため、繰り返されるグループの周りに2番目のキャプチャグループを配置する必要があります。!((abc|123)+)!。この正規表現が!abc123!にマッチすると、キャプチャグループ#1はabc123を格納し、グループ#2は123を格納します。内部グループのマッチには関心がないため、内部グループを非キャプチャにすることでこの正規表現を最適化できます。!((?:abc|123)+)!.
| クイック スタート | チュートリアル | ツール & 言語 | 例 | リファレンス | 書籍 レビュー |
| 正規表現の例 | 数値範囲 | 浮動小数点数 | メールアドレス | IPアドレス | 有効な日付 | 数値日付をテキストに変換 | クレジットカード番号 | 完全な行のマッチング | 重複行の削除 | プログラミング | 近くにある2つの単語 |
| 壊滅的なバックトラッキング | 過剰な繰り返し | サービス拒否 | すべてをオプションにする | 繰り返しキャプチャグループ | Unicodeと8ビットの混合 |
ページURL: https://regular-expressions.dokyumento.jp/captureall.html
ページ最終更新日: 2019年11月22日
サイト最終更新日: 2024年3月15日
Copyright © 2003-2024 Jan Goyvaerts. All rights reserved.