匹配包含{word}但不包含{2ndword}的文本

2024-04-20 09:30:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我编写了一个正则表达式(在得到一些非常好的帮助here)来过滤python文件中的所有函数。所以现在,我的老板只想要包含OpenSession但不包含会话。关闭()。你知道吗

我读了article about Lookarounds,但老实说,即使读了很多遍,我还是无法习惯它。但我认为这是普遍缺乏对regex的理解。无论什么。。。你知道吗

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

有人能帮我解释一下步骤吗?这样我就可以从中学到东西了?你知道吗


Tags: 文件函数namehereparameterisdefarticle
1条回答
网友
1楼 · 发布于 2024-04-20 09:30:48

只获取所有函数,然后根据它们是否包含OpenSession和不包含Session.Close()对它们进行过滤,当然会更容易(更可读,更主表)。但这是可能的。我只关注你表达的body部分。为了检查是否有OpenSession到来,我们把它放到前面的look中。但是向前看只检查当前位置,所以我们需要允许任意多个字符在中间:

(?=.*OpenSession)

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

(?=(?:(?!def).)*OpenSession)

因此,如果一个函数不包含OpenSession,那么这个模式将不匹配。为了排除包含Session.Close的函数,我们使用了类似于lookahead中使用的技巧。我们试图进入下一个def而不超越Session.Close

(?=(?:(?!def).)*OpenSession)(?:(?!Session[.]Close).)*?

原始模式末尾的前瞻性将确保您能够以这种方式使用整个函数体。还要注意的是,通过避免非贪婪的重复,可以稍微提高性能。您也可以通过将def添加到第二个lookahead来实现这一点:

(?=(?:(?!\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|$)

我不知道你想用lookarounds结尾的?来完成什么,但是他们所做的只是让最后一个字符成为可选的。你知道吗

还要注意,这种模式通常有点危险,因为函数中可能有一个多行字符串,它包含\ndef,在这种情况下regex不会返回整个函数。你知道吗

正如HamZa在一篇评论中提到的,您可能希望在每个OpenSessionSession.Closedef周围放置单词边界\b,以免在getOpenSession()Session.Closeddefine上出错。你知道吗

相关问题 更多 >