python正则表达式条件子串提取

时间:2012-09-03 13:18:38

标签: python regex logging python-2.6

我正在打开这个问题,因为我原来的问题似乎需要一个新方向:my original question

我想创建一个正则表达式,可以从以下类型的日志条目中提取STATIC MESSAGE和DYNAMIC MESSAGE:

  

/long/file/name/with.dots.and.extension:Jan 01 12:00:00 TYPE Static   消息;动态消息

     

/long/file/name/with.dots.and.extension:Jan 01 12:00:00 MODULE.NAME   TYPE THREAD.OR.CONNECTION.INFORMATION静态消息;动态消息

一个日志条目类型具有简单的结构:

file:date TYPE STATIC;DYNAMIC

另一个在尝试使用正则表达式进行解析时并不那么简单:

file:date MODULE.NAME TYPE CONNECTION.OR.THREAD STATIC;DYNAMIC

MODULE.NAMECONNECTION.OR.THREAD要么存在,要么不存在。

到目前为止,我的正则表达式适用于第一种类型的日志条目:

(?:.*?):(?:\w{3} \d{1,2} \d{1,2}:\d{1,2}:\d{1,2})(?:\s+?)(?:[\S|\.]*?(?:\s*?))?(?:(?:TYPE1)|(?:TYPE2)|(?:TYPE3))(?:\s+?)(?:\S+?(?:\s+?))?(.+){1}(?:;(.+)){1}

但每当我进入第二种类型的条目时,我也将CONNECTION.OR.THREAD作为我第一个捕获组的一部分。

我希望有一种方法可以使用前瞻或后瞻功能,以便我可以捕获STATICDYNAMIC,如果有CONNECTION.OR.THREAD则忽略MODULE.NAME部分?

我希望这个问题很明确,如果看起来有些暗淡,请参考我原来的问题。谢谢。

编辑:以便澄清。日志的每一行都与其他行不同,每行以文件路径开头,然后是:然后是日期,格式如下:MMM DD HH:MM:SS然后它变得棘手,要么{{1}变化后,MODULE.NAME也会变化,其后TYPE变化,或只变CONNECTION.OR.THREAD。之后有TYPE然后STATIC MESSAGE然后;静态和动态消息都会发生变化,术语DYNAMIC MESSAGE的使用仅仅是因为错误可能是实例“无法连接到服务器; server1.com”,因此错误的静态部分是“无法连接到服务器”,动态部分是“server1.com”

1 个答案:

答案 0 :(得分:0)

目前我制作了这个庞大的正则表达式:

(?:(?:.*?):(?:\w{3}(?: \d{1,2}){2}(?::\d{1,2}){2}))(?:\s+?)(?:(?:(?:(?:TYPE1)|(?:(?:TYPE1)|(?:TYPE3))(?:\s+?)(?:(.+){1};(.+){1}))|(?:\S+(?:\.\S+)+)(?:\s+?)(?:(?:TYPE1)|(?:TYPE1)|(?:TYPE3))(?:\s+?)(?:\S+(?:\.\S+)+)(?:\s+?)(?:(.+){1};(.+){1})))

我将它分成几部分:

文件/日期+空间:

(?:(?:.*?):(?:\w{3}(?: \d{1,2}){2}(?::\d{1,2}){2}))(?:\s+?)

然后是:

简单:( TYPE STATIC; DYNAMIC)

(?:(?:(?:TYPE1)|(?:TYPE1)|(?:TYPE3))(?:\s+?)(?:(.+){1};(.+){1}))

OR COMPLEX :( MODULE.NAME TYPE CONNECTION.OR.THREAD STATIC; DYNAMIC)

(:?(?:\S+(?:\.\S+)+)(?:\s+?)(?:(?:TYPE1)|(?:TYPE1)|(?:TYPE3))(?:\s+?)(?:\S+(?:\.\S+)+)(?:\s+?)(?:(.+){1};(.+){1}))

它可以解决问题。但它的巨大,我认为它可以改善。所以,如果有人能改进它,请做。

修改

但是有一个问题。因为现在有4个捕获组。所以我不能提前知道我是否必须查看捕获的[0:1]或捕获[2:3]以获得我的结果。任何人都有办法做到这一点,我不会每次检查我有什么东西吗?或者可能是从结果中消除空捕获组的方法,或者可能只从结果列表中获取非空结果?什么?我的大脑很油炸。

EDIT2:

正如@martijn pieters建议我删除了无关的分组,这是我现在的正则表达式:

.*?:\w{3}(?: \d{1,2}){2}(?::\d{2}){2}\s+?(?:(?:(?:TYPE1|TYPE2|TYPE3)\s+?(.+){1};(.+){1})|(?:\S+(‌​?:\.\S+)+\s+?(?:TYPE1|TYPE2|TYPE3)\s+?\S+(?:\.\S+)+\s+?(.+){1};(.+){1}))

工作正常。我担心(?:TYPE1|TYPE2|TYPE3)被错误解释为TYPE(1|T)YPE(2|T)YPE3任何见解都会受到赞赏。

另外,如何最好地解析我的结果 - 看到我会得到4个项目的列表,前两个或第二个2为空,另一个有静态/动态结果。

EDIT3:

好吧,我已经完成了混合解决方案。我重新制作了我的正则表达式:

.*?:\w{3}(?: \d{1,2}){2}(?::\d{2}){2}\s+?(?:(?:(?:TYPE1|TYPE2|TYPE3))|(?:\S+(?:\.\S+)+\s+?(?:TYPE1|TYPE2|TYPE3)\s+?\S+(?:\.\S+)+))\s+(.*)

我现在只有1个捕获组,即STATIC; DYNAMIC部分。一旦我得到这个,我就做我以前做过的事情(见我的previous question

for item in captured:
    parts = item.split(";")
    static = parts[0]
    dynamic = ";".join(parts[1:])

这是我的解决方案。谢谢你@Martijn Pieters特别感谢你的帮助。我希望这可以帮助将来的某个人。