匹配包含{word}但不包含{secondword}的文字

For*_*una 2 c# python regex

我写了一个正则表达式(经过一番很大的帮助这里),它从一个Python文件过滤器的所有功能.所以现在,我的老板只想要包含OpenSession而不是Session.Close()的函数.

我读过关于Lookarounds文章,但说实话,即使经过多次阅读,我也无法使用它.但我认为它普遍缺乏正则表达式的理解.随你...

我的尝试失败了,最后一个是: (?is)def\s*(?<name>\w+)\s*\((?<parameter>[^)]+)\)\s*:\s*(?:\r?\n)+(?<body>(?<=OpenSession?).*?(?=Session\.Close?))(?=\r?\ndef|$)

有人可以帮助我,也许可以解释一下这些步骤,所以我可以从中学习吗?

Mar*_*der 5

这肯定会更容易(更易读,更maintable)只得到所有的功能,然后通过是否含有它们进行过滤OpenSession,并且不包含Session.Close().虽然有可能.我只关注body你表达的部分内容.为了检查是否有一个OpenSession即将到来,我们将其展望未来.但是前瞻只检查当前位置,所以我们需要在两者之间允许任意多个字符:

(?=.*OpenSession)
Run Code Online (Sandbox Code Playgroud)

问题是,这可以OpenSession在下一个函数中找到.所以我们需要确保.*不能超越下一个def.为此,在使用每个字符之前,我们需要检查它是否标记了a的开头def(使用另一个 向前瞻):

(?=(?:(?!def).)*OpenSession)
Run Code Online (Sandbox Code Playgroud)

所以现在模式将不匹配函数,如果它不包含OpenSession.为了排除包含的函数Session.Close,我们使用了与前瞻中使用的类似技巧.我们试图进入下一个,def而不是超越Session.Close:

(?=(?:(?!def).)*OpenSession)(?:(?!Session[.]Close).)*?
Run Code Online (Sandbox Code Playgroud)

原始图案末尾的前瞻将确保您能够以这种方式使用整个功能体.另请注意,通过避免非贪婪的重复,您可以略微提高性能.你可以通过添加def到第二个前瞻来做到这一点:

(?=(?:(?!\r?\ndef).)*OpenSession)(?:(?!Session[.]Close|\r?\ndef).)*
Run Code Online (Sandbox Code Playgroud)

所以表达式看起来像:

(?is)def\s+(?<name>\w+)\s*\((?<parameter>[^)]+)\)\s*:\s*(?:\r?\n)+(?<body>(?=(?:(?!\r?\ndef).)*OpenSession)(?:(?!Session[.]Close|\r?\ndef).)*)(?=\r?\ndef|$)
Run Code Online (Sandbox Code Playgroud)

我不知道你想要?在你的外观结束时完成什么,但他们所做的就是让最后一个角色成为可选的.

还要注意,模式通常有点危险,因为你可能在函数中有一个多行字符串,包含\ndef,在这种情况下,正则表达式不会返回整个函数.

由于哈姆扎在评论中提到,你可能想要把字边界\b周围的每一个OpenSession,Session.Close并且def,以免绊倒的getOpenSession(),Session.Closeddefine.