匹配'//';或EOL'$';在正则表达式中,分组时会产生不一致的结果(在Python中)?

匹配'//';或EOL'$';在正则表达式中,分组时会产生不一致的结果(在Python中)?,python,regex,Python,Regex,有人知道为什么这两个正则表达式在尝试匹配“//”或“$”时给出不同的结果吗?(Python 3.6.4) (a)(//$):匹配“a”和“a//” (a)(//)|($):匹配“a//”,但不匹配“a” >>at=re.compile('(a)(//|$)) >>>m=at.match('a') >>>m >>>m=at.match('a/')) >>>m >>> vs >>at=re.compile(‘(a)(/)|($)’) >>>m=at.match('a/')) >>>m >>>

有人知道为什么这两个正则表达式在尝试匹配“//”或“$”时给出不同的结果吗?(Python 3.6.4)

  • (a)(//$)
    :匹配“a”和“a//”
  • (a)(//)|($)
    :匹配“a//”,但不匹配“a”
>>at=re.compile('(a)(//|$))
>>>m=at.match('a')
>>>m
>>>m=at.match('a/'))
>>>m
>>> 
vs

>>at=re.compile(‘(a)(/)|($)’)
>>>m=at.match('a/'))
>>>m
>>>m=at.match('a')
>>>m
>>>类型(m)
>>>

在计算之前,正则表达式引擎将对管道两侧的表达式进行分组。 在第一种情况下

  • (a)(//|$)

    表示它将匹配必须在之前有
    a
    的字符串
    /
    $
    (即EOL)

    因此,在这种情况下,第一个备选方案是
    /
    ,第二个备选方案是
    $
    ,两者都必须遵循
    a

    在此表达式中,捕获组为

    • a
    • /
      $
  • (a)(//)|($)

    表示它将匹配必须是
    a/
    $
    的字符串

    因此,在这种情况下,第一个备选方案是
    a/
    ,第二个备选方案是
    $

    在此表达式中,捕获组为

    或者

    • a
    • /

    • $
事实上,在第二个示例中,分组并不重要,
a/$
将给出相同的结果,因为正则表达式引擎将对其求值为
(a/)|$
(注意,对于我的示例,括号只是符号,它们并不表示捕获组语法)


在一个房间里试一试。它将告诉您每个表达式的可选项是什么

|
的优先级较低,因此
(a)(//)|($)
表示
((a)(/)|($)
,因此它要么是数学
(/)
,要么是
($)
。要获得与第一个类似的结果,请使用
(a)((//)|($)
,这与添加了组的第一个相同。第一个正则表达式比较干净,除非您需要组匹配,否则应该首选它


有关优先级的更多详细信息,请参见此处-

请查看此处-这很有意义!感谢您的帮助:)@Jo el欢迎使用stack overflow,如果您找到了要查找的内容,请单击答案旁边的勾号图标以指示正确答案。这确保了如果有人带着相同的问题再次来到这里,他们可以在顶部查看正确的答案。由于某种原因,我上次在这里检查时没有看到复选标记-可能是我的登录过期了,或者是其他什么-我曾想,既然这是重复的,我可能无法再“接受”答案了[有一个问题没有涉及到本案的细节.。]再次感谢:)事实上,请继续跟进。这是正确的思考方式吗?它试图抓住整个“单词”在它之前和之后?例如
12 | 3
应该匹配
12
13
?所以我的错误是认为在(a)和(//)周围添加组会破坏优先级,当在regex中实际上它们仍然是相同的“单词”。这是正确的吗?
在不使用
它将假定它之前的所有内容都是第一个备选方案,之后的所有内容都将被视为第二个备选方案。
12 | 3
将匹配
12
3
更多
    >>> at = re.compile('(a)(//|$)')
    >>> m = at.match('a')
    >>> m
    <_sre.SRE_Match object; span=(0, 1), match='a'>
    >>> m = at.match('a//')
    >>> m
    <_sre.SRE_Match object; span=(0, 3), match='a//'>
    >>> 
    >>> at = re.compile('(a)(//)|($)')
    >>> m = at.match('a//')
    >>> m
    <_sre.SRE_Match object; span=(0, 3), match='a//'>
    >>> m = at.match('a')
    >>> m
    >>> type(m)
    <class 'NoneType'>
    >>>