为什么这个python只捕获一个数字?

时间:2015-03-22 04:24:29

标签: python regex

我正在尝试使用python RE模块捕获'03'' video [720P] [DHR] _sp03.mp4 '等字符串的特定数字。

令我困惑的是:

当我使用'.*\D+(\d+).*mp4'时,它成功捕获了两个数字03, 但是当我使用'.*\D*(\d+).*mp4'时,它只捕获了后面的数字3

我知道python使用贪婪模式作为默认模式,这意味着尝试匹配尽可能多的文本。考虑到这一点,我认为*之后+\D的行为应该相同。那我在哪里错了?是什么导致了这种差异?任何人都可以帮忙解释一下吗?

BTW:我使用python的在线正则表达式测试器:https://regex101.com/#python

2 个答案:

答案 0 :(得分:7)

区别的不是\D+,而是第一个.*

现在在正则表达式中.*是贪婪的,并尝试尽可能多地匹配字符

所以当你写

.*\D*(\d+).*mp4

.*将尽可能多地匹配。也就是说,如果我们试图将其分解,它看起来就像

video [720P] [DHR] _sp03.mp4
|
.*

video [720P] [DHR] _sp03.mp4
 |
 .*
.....

video [720P] [DHR] _sp03.mp4
                      |
                      .* That is 0 is also matched by the .

video [720P] [DHR] _sp03.mp4
                      |
                      \D* Since the quantfier is zero or more, it matches nothing here without advancing to 3

video [720P] [DHR] _sp03.mp4
                       |
                      (\d+)

video [720P] [DHR] _sp03.mp4
                        |
                        .*

video [720P] [DHR] _sp03.mp4
                          |
                         mp4

现在当我们使用\D+时,匹配会稍微改变一下,因为正则数据引擎将被强制匹配至少1个非数字(\D+)之前的数字((\d+) )。这将消耗p,这是数字

之前的最后一位非数字

那是

.*将尝试尽可能多地匹配到p,以便\D+可以匹配至少一个非数字p和{{1} }}会匹配\d+部分

03

答案 1 :(得分:1)

问题在于\ D *。 '+'表示一个或多个,'*'表示零或更多。

正如您在启动时使用'。*'变得贪婪并直到'视频[720P] [DHR] _sp0'在'\ D +'的情况下它退出'视频[720P] [DHR] _s'离开\'+ D +

的'p'
>>> import re
>>> a = " video [720P] [DHR] _sp03.mp4 "
>>> p1 = re.compile('.*\D+(\d+).*mp4')
>>> p2 = re.compile('.*\D*(\d+).*mp4')
>>> re.findall(p1,a)
['03']
>>> re.findall(p2,a)
['3']
>>> a
' video [720P] [DHR] _sp03.mp4 '
>>> p3 = re.compile('(.*)(\D*)(\d+)(.*)mp4')
>>> re.findall(p3,a)
[(' video [720P] [DHR] _sp0', '', '3', '.')]
>>> p4 = re.compile('(.*)(\D+)(\d+)(.*)mp4')
>>> re.findall(p4,a)
[(' video [720P] [DHR] _s', 'p', '03', '.')]