クイックスタート
チュートリアル
ツールと言語
リファレンス
書評
正規表現チュートリアル
はじめに
目次
特殊文字
非表示文字
正規表現エンジンの内部動作
文字クラス
文字クラスの減算
文字クラスの積集合
省略可能な文字クラス
ドット
アンカー
単語境界
オルタネーション
オプション項目
繰り返し
グループ化とキャプチャ
バックリファレンス
バックリファレンス、パート2
名前付きグループ
相対バックリファレンス
ブランチリセットグループ
フリースペースとコメント
Unicode
モード修飾子
アトミックグループ化
所有格量子化子
先行参照と後続参照
先行参照と後続参照、パート2
一致からテキストを除外する
条件式
バランスグループ
再帰
サブルーチン
無限再帰
再帰と量子化子
再帰とキャプチャ
再帰とバックリファレンス
再帰とバックトラッキング
POSIXブラケット式
ゼロ長のマッチ
マッチの継続
このサイトについて、さらに
はじめに
正規表現クイックスタート
正規表現チュートリアル
置換文字列チュートリアル
アプリケーションと言語
正規表現の例
正規表現リファレンス
置換文字列リファレンス
書評
印刷可能なPDF
このサイトについて
RSSフィードとブログ
RegexBuddy—Better than a regular expression tutorial!

再帰における量子化子

再帰の紹介では、どのようにa(?R)?zが一致するかを示します。aaazzz量子化子?は、先行するトークンをオプションにします。つまり、トークンを0回または1回繰り返します。つまり、a(?R)?zこの(?R)は、それに続く?によってオプションになります。正規表現が1回でもなく、3回も再帰を試行した理由が疑問に思われるかもしれません。

その理由は、再帰時に、正規表現エンジンが正規表現全体を試行する際に新たな開始を行うためです。すべての量子化子とオルタネーションは、エンジンが文字列を進めたことを除いて、再帰前のマッチングプロセスはまったく発生しなかったかのように動作します。正規表現エンジンは、再帰が成功したか失敗したかにかかわらず、再帰から終了するときに、すべての量子化子とオルタネーションの状態を復元します。基本的に、マッチングプロセスは、エンジンが文字列を進めたことを除いて、再帰が発生しなかったかのように通常どおり継続されます。

手続き型プログラミング言語に精通している場合、正規表現の再帰は基本的に再帰関数呼び出しであり、量子化子は関数内のローカル変数です。関数の各再帰は、スタックの上位にある再帰の同じローカル変数に影響を与えず、影響を受けない独自のローカル変数のセットを取得します。Boostを除くすべてのフレーバーで、再帰時の量子化子はこのように機能します。

では、a(?R){3}z|qがどのように動作するかを見てみましょう(Boostを除く)。最も単純なマッチはqであり、正規表現の2番目のオルタネーションによって検出されます。

最初のオルタネーションが一致する最も単純なマッチはaqqqzです。後aが一致すると、正規表現エンジンは再帰を開始します。aは一致しません。q再帰内では、エンジンは2番目のオルタネーションを試行します。qが一致するかを示します。qエンジンは、成功したマッチで再帰を終了します。エンジンは、量子化子{3}が1回繰り返しに成功したことを認識します。さらに2回の繰り返しが必要なため、エンジンは別の再帰を開始します。再び一致qします。量子化子の3回目の反復では、3回目の再帰がqに一致します。最後に、が一致するかを示します。最後に、z

と全体の一致が見つかりました。この正規表現はaqqzまたは. この正規表現はaqqqqz最後に、. またはとは一致しません。量子化子の3回目の反復中に、再帰が一致しないため失敗します。a(?R){3}aqqq, 最後に、と一致した後に4番目のq.

と一致しないため失敗します。この正規表現は、次のようなより長い文字列にも一致できます。aqaqqqzqzaqqqzこの文字列では、量子化子の2回目の反復時に、再帰がaaaqqaqqqzzaqqqzqzqaqqaaqqqzqqzzz.

Boostによる再帰における量子化子の処理方法

Boostは、再帰における量子化子の動作方法について独自の考えを持っています。再帰演算子に量子化子がまったく存在しない場合、または*を量子化子として持つ場合のみ、再帰は他のフレーバーと同じようにBoostで機能します。他の量子化子は、Boost 1.59以前とBoost 1.60以降、および他の正規表現フレーバーで非常に異なるマッチ(またはその欠如)につながる可能性があります。Boost 1.60は、Boostと他のフレーバーの違いを修正しようとしましたが、互換性のない異なる動作につながっただけです。

Boost 1.59以前では、再帰時の量子化子は、再帰スタック全体を通して反復と再帰の両方をカウントします。したがって、a(?R){3}z|qのBoost 1.59での可能なマッチには、aaaazzzz, aaaqzzz, aaqqzz, aaqzqz、およびaqaqzzzが含まれます。これらのすべてのマッチにおいて、再帰と反復の数は3になります。他のフレーバーでは、これらのマッチは検出されません。なぜなら、各再帰中に3回の反復が必要だからです。そのため、他のフレーバーは次のようなものにマッチできます。aaqqqzaqqqzaqqqzzaqqzaqqaqqqzzBoost 1.59は、これらの文字列内でのみaqqqzにマッチします。

Boost 1.60は、他のフレーバーと同様に各再帰レベルで量子化子を反復しようとしますが、正しく実行されません。再帰をオプションにする量子化子は、無限の繰り返しを許可します。そのため、Boost 1.60以降はa(?R)?za(?R)*zと同じように扱います。a(?R)?zがBoost 1.59では完全にマッチできなかった問題を修正しますが、aaazzz次のような、他のフレーバーではこの正規表現では見つからないマッチも許可します。aazazz量子化子がオプションでない場合、Boost 1.60は最初の再帰でのみマッチを許可します。そのため、a(?R){3}z|qは常にqaqqzaqqqz.

にのみマッチします。再帰時の量子化子のBoostの問題は、再帰トークンの親グループの量子化子にも影響を与えます。サブルーチン呼び出しの量子化子、および量子化子を持つグループの親グループへのサブルーチン呼び出しを含むグループの量子化子にも影響を与えます。

再帰内の他のトークンの量子化子

正規表現内の他のトークンの量子化子は、再帰中に通常どおり動作します。各再帰で個別に反復を追跡します。そのため、a{2}(?R)z|qが一致するかを示します。aaqz, aaaaqzz, aaaaaaqzzzなどです。aは各再帰中に2回一致する必要があります。

再帰内にあるが、再帰自体を繰り返さないこのような量子化子は、Boostで正しく機能します。