Python 即使存在';没有前瞻性吗?

Python 即使存在';没有前瞻性吗?,python,regex,pypi-regex,Python,Regex,Pypi Regex,在回答问题时,我想到了以下正则表达式: (?:(?!\2)(?:,foo=([^,]*),(?=())|.))*\2bar=2 (注意:此正则表达式需要) (简短解释:正则表达式依赖于这样一个事实,即lookaheads中的捕获组在匹配一次后不能更改其值,因此在找到第一个foo=后,(?=())将匹配,从这一点开始(?!\2)将始终失败。) 此正则表达式适用于问题中给出的两个示例: >>> pattern = r'(?:(?!\2)(?:,foo=([^,]*),(?=())

在回答问题时,我想到了以下正则表达式:

(?:(?!\2)(?:,foo=([^,]*),(?=())|.))*\2bar=2
(注意:此正则表达式需要)

(简短解释:正则表达式依赖于这样一个事实,即lookaheads中的捕获组在匹配一次后不能更改其值,因此在找到第一个
foo=
后,
(?=())
将匹配,从这一点开始
(?!\2)
将始终失败。)

此正则表达式适用于问题中给出的两个示例:

>>> pattern = r'(?:(?!\2)(?:,foo=([^,]*),(?=())|.))*\2bar=2'
>>> regex.match(pattern, 'baz=0,foo=1,bar=2,foo=3,bar=4').group(1)
'1'
>>> regex.match(pattern, 'baz=0,foo=1,foo=1,bar=2')
>>>
但是如果在
bar=2
之后出现
foo=
,就会发生奇怪的事情:

>>> # this doesn't match, as expected:
>>> regex.match(pattern, 'notfoo=1,bar=2')
>>> # but how the heck does it match this ?!
>>> regex.match(pattern, 'notfoo=1,bar=2,foo=3,')
<regex.Match object; span=(0, 14), match='notfoo=1,bar=2'>
>#这与预期不匹配:
>>>regex.match(模式“notfoo=1,bar=2”)
>>>#但它怎么能和这个匹配?!
>>>匹配(模式'notfoo=1,bar=2,foo=3')

如您所见,字符串
notfoo=1,bar=2,foo=3'
生成了一个匹配的
notfoo=1,bar=2
foo=3,
甚至不包括在匹配中,但是如果它被删除,正则表达式将不再匹配!这怎么可能?这是
regex
模块中的一个bug吗?

这实际上非常合理。这种行为的原因很简单:回溯

事件顺序如下:

  • 贪婪组
    (?:…)*
    一次前进一个字符,直到最后在
    ,foo=3,
  • 正则表达式尝试匹配
    bar=2
    ,但失败
  • 正则表达式一次回溯1个字符,直到
    bar=2
    匹配,给我们一个
    notfoo=1,bar=2
    的结果
  • 那么,我们能做些什么呢?我们可以将
    bar=2
    移动到贪婪组中,并使用另一个捕获组断言正则表达式匹配成功:

    (?:(?!\2)(?:,foo=([^,]*),(?=())bar=2()|.))*\3
    
    >>> pattern = r'(?:(?!\2)(?:,foo=([^,]*),(?=())bar=2()|.))*\3'
    >>> regex.match(pattern, 'baz=0,foo=1,bar=2,foo=3,bar=4').group(1)
    '1'
    >>> regex.match(pattern, 'baz=0,foo=1,foo=1,bar=2')
    >>> regex.match(pattern, 'notfoo=1,bar=2')
    >>> regex.match(pattern, 'notfoo=1,bar=2,foo=3,')
    >>>