Python正则表达式行为奇怪

时间:2013-03-30 00:58:00

标签: python regex

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

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

但是

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

返回'7464535'

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

1 个答案:

答案 0 :(得分: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

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