TL;DR: .NET の後読み内でキャプチャ (特にバランシング グループ) を使用すると、取得したキャプチャが変更されますが、違いはありません。.NET の後読みが予期した動作を妨げる原因は何ですか?
.NET のバランシング グループをいじる言い訳として、この他の質問に対する答えを見つけようとしていました。ただし、可変長の後読み内でそれらを機能させることはできません。
まず、この特定のソリューションを生産的に使用するつもりはないことに注意してください。それは学術的な理由によるものです。なぜなら、私が気付いていない可変長後読みで何かが起こっていると感じているからです。将来、問題を解決するためにこのようなものを実際に使用する必要がある場合に、それが役立つ可能性があることを知っています.
次の入力を検討してください。
~(a b (c) d (e f (g) h) i) j (k (l (m) n) p) q
目標は、 が前にある括弧内にあるすべての文字に一致することです (つまり、からまで~
のすべて)。私の試みは、後読みで正しい位置を確認することでした。これにより、 への 1 回の呼び出しですべての文字を取得できます。これが私のパターンです:a
i
Matches
(?<=~[(](?:[^()]*|(?<Depth>[(])|(?<-Depth>[)]))*)[a-z]
後読みで を見つけようとしてから~(
、名前付きグループ スタックを使用してDepth
不要な開き括弧を数えます。で開いた括弧~(
が決して閉じない限り、後読みは一致するはずです。への閉じ括弧に達した場合、(?<-Depth>...)
はスタックから何もポップできず、後読みは失敗します (つまり、 からのすべての文字に対してj
)。残念ながら、これは機能しません。代わりにa
、b
、c
、e
、f
、g
およびに一致しm
ます。したがって、これらのみ:
~(a b (c) _ (e f (g) _) _) _ (_ (_ (m) _) _) _
これは、以前に行った最高のネストレベルに戻らない限り、単一の括弧を閉じると、後読みは何にも一致しないことを意味するようです。
これは、私の正規表現に奇妙な点があるか、バランス グループを正しく理解していなかったことを意味している可能性があります。しかし、私は後読みなしでこれを試しました。次のように、すべての文字の文字列を作成しました。
~(z b (c) d (e f (x) y) g) h (i (j (k) l) m) n
~(a z (c) d (e f (x) y) g) h (i (j (k) l) m) n
~(a b (z) d (e f (x) y) g) h (i (j (k) l) m) n
....
~(a b (c) d (e f (x) y) g) h (i (j (k) l) z) n
~(a b (c) d (e f (x) y) g) h (i (j (k) l) m) z
そして、それらのそれぞれでこのパターンを使用しました:
~[(](?:[^()]*|(?<Depth>[(])|(?<-Depth>[)]))*z
そして、必要に応じて、すべてのケースが一致し、とz
の間の文字を置換し、その後のすべてのケースが失敗します。a
i
では、(可変長の) 後読みは、このバランシング グループの使用を破るものでしょうか? 私はこれを一晩中調査しようとしましたが (そして、このようなページを見つけました)、後読みでこれを 1 回も使用する方法を見つけることができませんでした。
また、.NET 正規表現エンジンが .NET 固有の機能を内部でどのように処理するかについての詳細な情報に誰かが私をリンクしてくれたら嬉しいです。この素晴らしい記事を見つけましたが、たとえば、(可変長の) 後読みには入っていないようです。