不明白懒惰的regex

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

假设我们有一个字符串 1abcd1efg1hjk1lmn1 并想在之间找到东西 1-s. 我们做的是

re.findall('1.*?1','1abcd1efg1hjk1lmn1')

并得到两个结果

['1abcd1', '1hjk1']

好吧,我明白了。但如果我们做

re.findall('1.*?1hj','1abcd1efg1hjk1lmn1')

为什么它抓取两个间隔之间的 1而不是一个? 为什么我们会得到 ['1abcd1efg1hj'] 而不是 ['1efg1hj']? 这不是懒惰应该做的吗?

python regex lazy-evaluation
2个回答
5
投票

Regex总是试图从左到右匹配输入字符串。考虑一下你的 '1.*?1hj' regex. 1 中的内容与第一条和下面的内容相匹配。.*? 匹配所有字符,直到 1hj 子串非贪婪地。这样,你就得到了 ['1abcd1efg1hj'] 而不是 ['1efg1hj']

要获得 ['1efg1hj'] 作为输出,你需要使用一个否定类作为 1[^1]*1hj

>>> s = "1abcd1efg1hjk1lmn1"
>>> re.findall(r'1.*?1hj', s)
['1abcd1efg1hj']
>>> re.findall(r'1[^1]*1hj', s)
['1efg1hj']

0
投票
['1abcd1efg1hj']

你得到这个,因为这满足了你的regex。1.*?1hj 基本上意味着从 1 缓缓而行 1 其次 hj. 该 1 其间 ef 所以,这将无法匹配,但 . 会消耗所有。你不会得到 ['1efg1hj'] 因为该字符串已经被第一个匹配消耗掉了.使用lookahead查看两者是否满足条件。请看演示。

lookahead不消耗字符串,所以你会得到两个匹配的字符串。

https:/regex101.comraQ3zJ35

© www.soinside.com 2019 - 2024. All rights reserved.