我正在尝试使用python RE模块捕获'03'
中' video [720P] [DHR] _sp03.mp4 '
等字符串的特定数字。
令我困惑的是:
当我使用'.*\D+(\d+).*mp4'
时,它成功捕获了两个数字03
,
但是当我使用'.*\D*(\d+).*mp4'
时,它只捕获了后面的数字3
。
我知道python使用贪婪模式作为默认模式,这意味着尝试匹配尽可能多的文本。考虑到这一点,我认为*
之后+
和\D
的行为应该相同。那我在哪里错了?是什么导致了这种差异?任何人都可以帮忙解释一下吗?
BTW:我使用python的在线正则表达式测试器:https://regex101.com/#python
答案 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', '.')]