我试图像这样解析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
当然,我可以改为贪婪模式或使用行尾字符($
),但我想了解为什么它不像我预期的那样工作: )
答案 0 :(得分:2)
非贪婪意味着它将尽可能少地匹配,同时仍然允许整个比赛成功。 *
表示"零或更多"。所以它可以匹配的最小值是零。所以它匹配为零,匹配成功。
正则表达式中.*?
的其他匹配项无法匹配为零,因为整个正则表达式将无法匹配。
答案 1 :(得分:1)
您的上一个(.*?)
匹配尽可能少的字符。要匹配Cookie的其余部分,您必须设置前瞻或匹配已知字符。
这是一个先行的解决方案:
(.*?)=(.*?); path=(.*?); domain=(.*?)(?=;\s|$)
请参阅demo
顺便说一句,regex101非常有助于了解正则表达式背后的内容:转到正则表达式调试器并单击右侧的+
,然后你就可以了看看当你的正则表达式到达最后(.*?)
时到底发生了什么:
所以,这就是我在开头所说的:匹配尽可能少。它在=
符号后面匹配一个空字符串,其余部分可以“放弃”,因为这是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('='),)}