2

我有一个关于 Python 正则表达式的问题。我没有太多关于 Python 正则表达式的信息。我正在处理 HTTP 请求消息并使用正则表达式解析它们。如您所知,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 的位置在消息中发生了变化。

4

2 回答 2

4

可读性很重要(Python 之禅)

用于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)']
于 2012-05-31T11:54:25.600 回答
2

像这样将整个标题解析成字典?

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']
于 2012-05-31T11:57:57.907 回答