打印出可选的正则表达式

时间:2014-01-24 20:50:16

标签: python regex

我正在尝试打印存储在字典中的值。这些值是从正则表达式创建的。

目前我有一些可选字段,但我不确定我是否正确执行此操作

(field A(field B)? field C (field D)?)?

我读了一个快速参考,它说?表示0或1次出现。

当我尝试搜索reputationcontent-type等字段时,我得到None,因为这些字段在我的正则表达式中是可选的。我可能有错误的正则表达式,但我想知道为什么每当我搜索可选字段(...)?时它会打印出None

我的代码:

import re

httpproxy515139 = re.compile(r'....url\=\"(?P<url>(.*))\"(\s+exceptions\=\"(?P<exceptions>([^\"]*))\"\s+error\=\"(?P<error>([^\"]*))\"\s+(reputation\=\"(?P<reputation_opt>([^\"]*))\"\s+)?category\=\"(?P<category>([^\"]*))\"\s+reputation\=\"(?P<reputation>([^\"]*))\"\s+categoryname\=\"(?P<categoryname>([^\"]*))\"\s+(content-type\=\"(?P<content_type>([^\"]*))\")?)?')

f  = open("sophos-httpproxy.out", "r")
fw = open("sophosfilter.log", "w+")

HttpProxyCount = 0
otherCount = 0

for line in f.readlines():
    HttpProxy = re.search(httpproxy515139, line)
    HttpProxy.groupdict()

    print "AV Field: "
    print "Date/Time: " + str(HttpProxy.groupdict()['categoryname'])

这是完整的正则表达式:

(?P<datetime>\w\w\w\s+\d+\s+\d\d:\d\d:\d\d)\s+(?P<IP>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*httpproxy\[(?P<HTTPcode>(.*))\]:\s+id\=\"(?P<id>([^\"]*))\"\s+severity\=\"(?P<Severity>([^\"]*))\"\s+sys\=\"(?P<sys>([^\"]*))\"\s+sub\=\"(?P<sub>([^\"]*))\"\s+name\=\"(?P<name>([^\"]*))\"\s+action\=\"(?P<action>([^\"]*))\"\s+method\=\"(?P<method>([^\"]*))\"\s+srcip\=\"(?P<srcip>([^\"]*))\"\s+dstip\=\"(?P<dstip>([^\"]*))\"\s+user\=\"(?P<user>[^\"]*)\"\s+statuscode\=\"(?P<statuscode>([^\"]*))\"\s+cached\=\"(?P<cached>([^\"]*))\"\s+profile\=\"(?P<profile>([^\"]*))\"\s+filteraction\=\"(?P<filteraction>([^\"]*))\"\s+size\=\"(?P<size>([^\"]*))\"\s+request\=\"(?P<request>([^\"]*))\"\s+url\=\"(?P<url>(.*))\"(\s+exceptions\=\"(?P<exceptions>([^\"]*))\"\s+error\=\"(?P<error>([^\"]*))\"\s+(reputation\=\"(?P<reputation_opt>([^\"]*))\"\s+)?category\=\"(?P<category>([^\"]*))\"\s+reputation\=\"(?P<reputation>([^\"]*))\"\s+categoryname\=\"(?P<categoryname>([^\"]*))\"\s+(content-type\=\"(?P<content_type>([^\"]*))\")?)?

以下是输入示例:

  

Oct 7 13:22:55 192.168.10.2 2013:10:07-13:22:54 httpproxy [15359]:id =“0001”severity =“info”sys =“SecureWeb”sub =“http”name =“http access”action =“pass”method =“GET”srcip =“192.168.8.47”dstip =“64.94.90.108”user =“”statuscode =“200”cached =“0”profile =“REF_DefaultHTTPProfile(默认代理) )“filteraction =”REF_DefaultHTTPCFFAction(默认内容过滤器操作)“size =”1502“request =”0x10870200“url =”http://www.concordmonitor.com/csp/mediapool/sites/dt.common.streams.StreamServer。 CLS STREAMOID = 6rXcvJGqsPivgZ7qnO $骰$ daE2N3K4ZzOUsqbU5sYvZF78hLWDhaM8n_FuBV1yRWCsjLu883Ygn4B49Lvm9bPe2QeMKQdVeZmXF $9升$ 4uCZ8QDXhaHEp3rvzXRJFdy0KqPHLoMevcTLo3h8xh70Y6N_U_CryOsw6FTOdKL_jpQ-和放大器; CONTENTTYPE =图像/ JPEG”例外= “” 错误= “” 类别= “134” 的信誉= “中性” 类别名称= “一般新闻” 内容类型= “图像/ JPEG”

我试图捕获整个日志

然而,有时url中有许多引号会让事情变得混乱。此外,在某些日志中,reputation和声誉之间还有一个额外的error数据字段。 content-type也并非总是出现。有时,url数据字段之后的所有内容都会丢失。这就是我添加所有可选?的原因。我试图考虑这些事件并在必要时打印None

1 个答案:

答案 0 :(得分:4)

让我们将你的正则表达式分成两部分:

....url\=\"(?P<url>(.*))\"

(\s+exceptions\=\"(?P<exceptions>([^\"]*))\"\s+error\=\"(?P<error>([^\"]*))\"\s+(reputation\=\"(?P<reputation_opt>([^\"]*))\"\s+)?category\=\"(?P<category>([^\"]*))\"\s+reputation\=\"(?P<reputation>([^\"]*))\"\s+categoryname\=\"(?P<categoryname>([^\"]*))\"\s+(content-type\=\"(?P<content_type>([^\"]*))\")?)?

第一部分中的.*是贪婪的。它会匹配它所能做到的一切,只有在绝对必要时才会回溯。

第二部分是一个巨大的可选组。

当正则表达式执行时,.*将匹配字符串末尾的所有内容,然后根据需要回溯,直到\"与引号匹配。那将是字符串中的最后一个引号,它可能不是你想要的那个。

然后,巨型可选组将尝试匹配,但由于贪婪的.*已经吃了巨大的可选组应该解析的所有内容,它将失败。由于它是可选的,因此正则表达式算法就可以了。

解决这个问题?好吧,非贪婪的量词可能有助于解决当前的问题,但更好的解决方案可能是停止尝试使用正则表达式来解析它。寻找您的数据格式的现有解析器。您是否尝试从HTML或XML中提取数据?我已经看到了BeautifulSoup的很多建议。