OpenSession
すべての関数を取得してから、 を含むか含まないかでフィルター処理する方が確かに簡単です (読みやすく、保守しやすくなります) Session.Close()
。でも可能です。body
ここでは、あなたの表現の部分だけに焦点を当てています。OpenSession
到来があるかどうかを確認するために、それを look aheadに入れます。ただし、先読みは現在の位置のみをチェックするため、その間に任意の多くの文字を許可する必要があります。
(?=.*OpenSession)
OpenSession
問題は、これが次の関数で見つかる可能性があることです。.*
したがって、 が次の を通過できないことを確認する必要がありdef
ます。def
そのためには、各文字を消費する前に、それが(別の否定的な 先読みで)の開始をマークしていないことを確認する必要があります。
(?=(?:(?!def).)*OpenSession)
そのため、含まれていない場合、パターンは関数と一致しませんOpenSession
。を含む関数を除外するためSession.Close
に、先読みで使用したのと同様のトリックを使用します。def
を超えることなく、次へと到達しようとしますSession.Close
。
(?=(?:(?!def).)*OpenSession)(?:(?!Session[.]Close).)*?
元のパターンの最後にある先読みにより、この方法で関数本体全体を使用できたことを確認できます。また、貪欲でない繰り返しを避けることで、おそらくパフォーマンスをわずかに改善できることに注意してください。def
これは、2 番目の先読みにも追加することで実行できます。
(?=(?:(?!\r?\ndef).)*OpenSession)(?:(?!Session[.]Close|\r?\ndef).)*
したがって、式は次のようになります。
(?is)def\s+(?<name>\w+)\s*\((?<parameter>[^)]+)\)\s*:\s*(?:\r?\n)+(?<body>(?=(?:(?!\r?\ndef).)*OpenSession)(?:(?!Session[.]Close|\r?\ndef).)*)(?=\r?\ndef|$)
ルックアラウンドの最後にを使用して何を達成したかったのかはわかりませんが?
、最後の文字をオプションにしただけです。
また、関数内に を含む複数行の文字列が含まれている可能性があるため、このパターンは一般的に少し危険であることに注意してください。\ndef
この場合、正規表現は関数全体を返しません。
HamZa がコメントで述べたように、 、 、 につまずかないように、 、 、 の周りに単語境界を配置することをお勧め\b
します。OpenSession
Session.Close
def
getOpenSession()
Session.Closed
define