HTTP请求头的Python正则表达式

HTTP请求头的Python正则表达式,python,regex,regex-negation,Python,Regex,Regex Negation,我有一个关于Python正则表达式的问题。我没有太多关于Python正则表达式的信息。我正在处理HTTP请求消息,并使用regex解析它们。如您所知,HTTP GET消息采用这种格式 GET / HTTP/1.0 User-Agent: Wget/1.12 (linux-gnu) Accept: */* Host: 10.2.0.12 Connection: Keep-Alive 我想解析URI、方法、用户代理和消息的主机区域。我对这项工作的正则表达式是: r'^({0})\s+(\S+)\s

我有一个关于Python正则表达式的问题。我没有太多关于Python正则表达式的信息。我正在处理HTTP请求消息,并使用regex解析它们。如您所知,HTTP GET消息采用这种格式

GET / HTTP/1.0
User-Agent: Wget/1.12 (linux-gnu)
Accept: */*
Host: 10.2.0.12
Connection: Keep-Alive
我想解析URI、方法、用户代理和消息的主机区域。我对这项工作的正则表达式是:

r'^({0})\s+(\S+)\s+[^\n]*$\n.*^User-Agent:\s*(\S+)[^\n]*$\n.*^Host:\s*(\S+)[^\n]*$\n'.format('|'.join(methods)), re.MULTILINE|re.DOTALL)
但是,当信息出现时

GET / HTTP/1.0
Host: 10.2.0.12
User-Agent: Wget/1.12 (linux-gnu)
Accept: */*
Connection: Keep-Alive
我无法捕捉到它们,因为主机位置或用户代理已更改。因此,我需要一个通用的正则表达式来捕获所有的正则表达式,即使消息中主机、方法、uri的位置发生了更改

可读性计数

对要查找的每个子表达式使用
findall()
。这样,正则表达式将变得简短、可读,并且独立于子表达式的位置

定义一个简单易读的正则表达式:

>>> user=re.compile("User-Agent: (.*?)\n")
使用两个不同的http头进行测试:

>>> s1='''GET / HTTP/1.0
    Host: 10.2.0.12
    User-Agent: Wget/1.12 (linux-gnu)
    Accept: */*
    Connection: Keep-Alive'''
>>> s2='''GET / HTTP/1.0
    User-Agent: Wget/1.12 (linux-gnu)
    Accept: */*
    Host: 10.2.0.12
    Connection: Keep-Alive'''
>>> user.findall(s1)
['Wget/1.12 (linux-gnu)']
>>> user.findall(s2)
['Wget/1.12 (linux-gnu)']

像这样将整个标题解析到字典中

headers = """GET / HTTP/1.0
Host: 10.2.0.12
User-Agent: Wget/1.12 (linux-gnu)
Accept: */*
Connection: Keep-Alive"""


headers = headers.splitlines()
firstLine = headers.pop(0)
(verb, url, version) = firstLine.split()
d = {'verb' : verb, 'url' : url, 'version' : version}
for h in headers:
    h = h.split(': ')
    if len(h) < 2:
        continue
    field=h[0]
    value= h[1]
    d[field] = value

print d

print d['User-Agent']
print d['url']
headers=“”获取/HTTP/1.0
主持人:10.2.0.12
用户代理:Wget/1.12(linux gnu)
接受:*/*
连接:保持活动状态“”
headers=headers.splitlines()
firstLine=headers.pop(0)
(动词、url、版本)=firstLine.split()
d={'verb':动词'url':url'version':version}
对于标题中的h:
h=h.split(“:”)
如果len(h)<2:
持续
字段=h[0]
值=h[1]
d[字段]=值
打印d
打印d['User-Agent']
打印d['url']

@tuxuday+1搜索奇怪的web是开发人员工具箱中最强大的技能。我喜欢@tuxuday所说的方法。类似于这个m=re.findall(r“(?P.*?):(?P.*?)\r\n”,req)。但是在这个方法中,我无法解析“GET”和http版本。在开始时添加它们是否更好?以正确的方式完成工作。使用
cgi.parse_header()
从字符串中获取值,或者使用诸如WebOb之类的工具。记住剥离您的值并忽略不包含
-
d=dict的行([[i.strip()表示l.split中的i(':')]表示s1中的l.splitlines()如果“:”表示“在l中”)
和+1-喜欢您的方法。正如我所写的,可读性很重要。我还需要解析“GET方法”。不带“:”已更新为包含第一行:)