Python正则表达式行为奇怪

aso*_*erg 3 python regex

url = "http://www.domain.com/7464535"
match = re.search(r'\d*',url)
match.group(0)
Run Code Online (Sandbox Code Playgroud)

返回''<-----空字符串

url = "http://www.domain.com/7464535"
match = re.search(r'\d+',url)
match.group(0)
Run Code Online (Sandbox Code Playgroud)

返回'7464535'

我以为'+'应该是1或更多,'*'是0或更正确?RE应该是贪婪的.那么为什么他们都没有返回同样的东西,更重要的是为什么第一个没有返回?

Sco*_*son 9

你对+和的意义是正确的*.所以\d*将匹配零个或多个数字 - 这正是它正在做的事情.从字符串的开头开始,它匹配零位数,然后就完成了.它成功匹配零个或多个数字.

*贪婪,但这只意味着它匹配的数字尽可能多.它不会放弃匹配以尝试在字符串中稍后找到更长的匹配.


编辑:正则表达式引擎的更详细描述:

以我们要搜索的字符串"http://www.domain.com/7464535"和模式为例\d+.

最初,正则表达式引擎指向URL的开头和正则表达式模式的开头.\d+需要匹配一个或多个数字,因此首先正则表达式引擎必须找到至少一个数字才能成功匹配.

它看起来第一个找到'h'字符.这不是一个数字,所以它会移动到't',然后是下一个't',依此类推,直到它最终到达'7'.现在我们匹配了一个数字,所以满足了"一个或多个"要求,我们可以有一个成功的匹配,除了+贪婪,所以它将匹配尽可能多的数字而不改变匹配的起点,' 7' .所以它命中字符串的末尾并匹配整数'7464535'.

现在考虑我们的模式是否\d*.现在唯一的区别是零位是有效匹配.由于正则表达式从左到右匹配,因此\d*匹配的第一个位置是字符串的开头.所以我们在开始时有一个零长度匹配,但由于*是贪婪的,只要有数字就会延长匹配.由于我们发现的第一件事是'h',一个非数字,它只返回零长度匹配.

*那么,如果它只是给你一个零长度的匹配,那怎么有用呢?考虑我是否匹配这样的配置文件:

foo: bar
baz:   quux
blah:blah
Run Code Online (Sandbox Code Playgroud)

我想在冒号后允许任意数量的空格(甚至为零).就像我会使用一个正则表达式(\w+):\s*(\w+),其中\s*零个或多个空格匹配.由于它出现在模式中的冒号之后,它将匹配字符串中的冒号之后,然后匹配零长度字符串(如第三行中,blah:blah因为冒号结束匹配后的'b')或全部在下一个非空间之前有空间,因为*是贪婪的.