re.search()中的非贪婪模式与字符串结尾不匹配

时间:2015-05-29 18:52:41

标签: python regex non-greedy

我试图像这样解析cookie的值:

import re
m = re.search("(.*?)=(.*?); path=(.*?); domain=(.*?)", "name=value1; path=/; domain=my.domain.com")
print (m.group(0))

我得到的结果是这样的:

name=value1; path=/; domain=

我的问题是:为什么它在最后的非贪婪位置不匹配?预期结果将是:

name=value1; path=/; domain=my.domain.com

当然,我可以改为贪婪模式或使用行尾字符($),但我想了解为什么它不像我预期的那样工作: )

3 个答案:

答案 0 :(得分:2)

非贪婪意味着它将尽可能少地匹配,同时仍然允许整个比赛成功。 *表示"零或更多"。所以它可以匹配的最小值是零。所以它匹配为零,匹配成功。

正则表达式中.*?的其他匹配项无法匹配为零,因为整个正则表达式将无法匹配。

答案 1 :(得分:1)

您的上一个(.*?)匹配尽可能少的字符。要匹配Cookie的其余部分,您必须设置前瞻或匹配已知字符。

这是一个先行的解决方案:

(.*?)=(.*?); path=(.*?); domain=(.*?)(?=;\s|$)

请参阅demo

顺便说一句,regex101非常有助于了解正则表达式背后的内容:转到正则表达式调试器并单击右侧的+,然后你就可以了看看当你的正则表达式到达最后(.*?)时到底发生了什么:

enter image description here

所以,这就是我在开头所说的:匹配尽可能少。它在=符号后面匹配一个空字符串,其余部分可以“放弃”,因为这是lazy matching所做的。

  

正则表达式中的标准量词是贪婪的,意思是   他们尽可能地匹配,只在必要时回馈才能匹配   正则表达式的其余部分。

     

通过使用延迟量词,表达式尝试最小匹配   第一

答案 2 :(得分:0)

其他答案很好地解释了为什么您的代码不能按原样运行。我只是指出,老实说,你应该贪婪地匹配非空格字符,而不是非贪婪地匹配所有字符。

re_obj = re.compile(r"""
    (\S*)=(\S*);\s*           # capture unknown key/value pair
    path=(\S*);\s*            # capture path
    domain=(\S*)              # capture domain""", re.X)

样本

>>> result = re_obj.search("name=value1; path=/; domain=my.domain.com")
>>> result.groups()
('name', 'value1', '/', 'my.domain.com')

更重要的是,使用字符串操作比使用

更容易
txt = "name=value1; path=/; domain=my.domain.com"
parameters = {key.strip(): value.strip() for parm in txt.split(';') for
              key,value in (parm.strip().split('='),)}