我正试着搂着Python RE模块。但是,我很难为什么python3认为findall()有两个匹配...
>>>import re
>>>re.match('\d{1,3}[-\s]?\d{1,3}[-\s]?\d{1,4}', '123-345--0987')
<_sre.SRE_Match object; span=(0, 7), match='123-345'>
>>>re.search('\d{1,3}[-\s]?\d{1,3}[-\s]?\d{1,4}', '123-345--0987')
<_sre.SRE_Match object; span=(0, 7), match='123-345'>
>>>re.findall('\d{1,3}[-\s]?\d{1,3}[-\s]?\d{1,4}', '123-345--0987')
['123-345', '0987']
我原本以为findall()调用与0987不匹配?我错过了什么?
答案 0 :(得分:0)
>>>re.findall('\d{1,3}[-\s]?\d{1,3}[-\s]?\d{1,4}', '123-345--0987')
['123-345', '0987']
为什么?
因为\d{1,3}
匹配的数字范围为1到3 贪婪。由于它是贪婪的,它会尝试匹配最大可能的东西,因此,123-345
匹配,并且由于双破折号,后面的--
无法匹配。然后它会尝试从剩余的字符串中找到匹配项,因此0987
已匹配 - "09" matched by \d{1,3}
,"8" matched by \d{1,3}
和"7" matched by \d{1,4}
。
123-345--0987 \d{1,3}
首先\d{1,3}
尝试贪婪地匹配所有三位数字。如果没有找到三位数,则它会尝试匹配2位数字,然后匹配一位数字。由于上面的模式是贪婪的,它匹配123
,345
和098
123-345--0987 \d{1,3}[-\s]?
然后它尝试匹配以下可选的-
或空格。因此,123-
,345-
,098
已匹配。
123-345--0987 \d{1,3}[-\s]?\d{1,3}
匹配的123-345
和0987
与第二个7
匹配,因为您定义的\d{1,3}
匹配数字范围从1到3(回溯发生这里)。
123-345--0987 \d{1,3}[-\s]?\d{1,3}[-\s]?
[-\s]?
匹配可选的空格字符或短划线。现在匹配123-345-
和0987
仍然保持不变。因为这种模式是可选的。
123-345--0987 \d{1,3}[-\s]?\d{1,3}[-\s]?\d{1,4}
为了提供匹配,所有贪婪匹配的123-345
回溯一步,而5
中的123-345
与最后\d{1,4}
模式匹配。请注意,它会删除先前匹配的-
中的123-345-
,因为5-
后面没有数字。现在,进行第二场比赛,即0987
。我们已经匹配,但是为了提供匹配,\d{1,4}
匹配上一个7
,\d{1,3}
匹配[-\s]?\d{1,4}
之前存在的8
模式匹配{{1}} 。回溯发生在这里。