非贪婪的通配符似乎与贪婪匹配?

问题描述 投票:0回答:2

我需要理解为什么不指定正则表达式时会贪婪地匹配。

给出string='.GATA..GATA..ETS..ETS.'

返回GATA ... ETS的最短子串

我使用正则表达式模式pattern = r'(GATA).*?(ETS)'

syntax_finder=re.compile(pattern,re.IGNORECASE)

for match in syntax_finder.finditer(string):
    print(match)

返回<re.Match object; span=(1, 17), match='GATA..GATA..ETS'>

但是,我希望它返回'GATA..ETS'

有人知道为什么会这样吗?

我不是在寻找针对此完全匹配问题的解决方案。我将使用更复杂的GATA和ETS模式进行很多此类搜索,但我将始终希望它返回最短的匹配项。

谢谢!

python search greedy
2个回答
0
投票

有人知道为什么会这样吗?

正则表达式非贪婪匹配。它找到第一个GATA,然后,因为使用了.*?而不是.*,所以匹配直到之后的first ETS。只是碰巧还有另一个GATA,您不想要-但是哪个非贪婪匹配并不在乎。

我将使用更复杂的GATA和ETS模式进行很多此类搜索

然后正则表达式可能无法胜任这项工作。我的建议是使用它们将字符串分成GATA,ETS和中间部分(tokenization),然后使用其他技术来查找该序列中的模式(parsing)。

我不是在寻找此精确匹配问题的解决方案。

但是我无法抗拒:)

>>> re.search(r'(GATA)((?<!GAT)A|[^A])*?(ETS)', '.GATA..GATA..ETS..ETS.')
<_sre.SRE_Match object; span=(7, 16), match='GATA..ETS'>

[这里我们使用否定的后向断言:在扫描GATAETS之间的部分时,仅当A之前没有GAT时,才允许它。


-1
投票

documentation,我们可以阅读:

re.finditer(pattern, string, flags=0)

返回一个迭代器,在字符串的RE模式的所有不重叠匹配中产生MatchObject实例。从左到右扫描字符串,并以找到的顺序返回匹配项。

因此,我猜测它直接来自以下事实:该函数返回所有非重叠匹配项],并且扫描字符串从左至右

换句话说,从左到右搜索字符串,任何下一次匹配尝试都将在前一次匹配之后开始。在这种特定情况下,将仅在“ GATA..GATA..ETS”之后的字符串中搜索匹配项。

现在,对于这个特定的示例,我想一种解决方案是以这种特定的方式(具有积极的超前断言)使用findall函数:

pattern = "(?=(GATA.*?ETS))"
syntax_finder=re.compile(pattern, re.IGNORECASE)
print(min(syntax_finder.findall(string), key=len))
© www.soinside.com 2019 - 2024. All rights reserved.