python来搜索文件并使用正则表达式进行解析

2024-04-25 21:56:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我是python新手。我试图编写一个快速而肮脏的python脚本来查找某些字符串日志文件并从该行中提取某些信息。日志文件中的行如下所示

2012-08-01 13:36:40,449 [PDispatcher: ] ERROR  Fatal error DEF_CON encountered. Shutting down
2012-08-01 14:17:10,749 [PDispatcher: ] INFO  Package 1900034442 Queued for clearance.
2012-08-01 14:23:06,998 [PDispatcher: ] ERROR Exception occurred attempting to lookup prod id 90000142

我有一个函数,其中输入参数将是一个文件名和一个要查找的模式数组。目前,我可以找到文件中包含一个或多个指定模式的所有行(尽管不确定这是否是最有效的方式),并且我能够提取行号和行。在

^{pr2}$

我想做的是在搜索时提取日期和时间。因此,我考虑将搜索模式修改为正则表达式字符串,并对其进行分组,以搜索和提取日期。只有一个问题,我不知道如何在python中做到这一点…任何帮助都将不胜感激。在

编辑(解决方案):在Sebastian和Joel提供的链接的帮助下,我想出了这个解决方案:

def search_logs(fn, searchPatterns):
    res = []
    with open(fn) as f:
        for lineNo, line in enumerate(f, 1):
            #check if pattern strings exist in line
            for sPattern in searchPatterns:
                #crude reg ex to match pattern and if matched, 'group' timestamp
                rex = r'^(.+) \[.*' + pattern 
                ms = re.match(rex, line)
                if ms:
                    time = ms.group(1)
                    item = Structs.MatchedItem(fn, pattern, lineNo, line, time)
                    res.append(item)
    return res

search_logs("c:\temp\app.log", ["ERROR", "DEF_CON"]) #this should return 3 elements based on the above log snipped (2 for the first line and 1 for the third line)

Tags: 文件the字符串inforifdefline
2条回答

有两部分:

  • 提取日期时间字符串
  • 将其解析为datetime对象

对于后者,您可以使用^{} function

try:
    dt = datetime.strptime(line.split(" [", 1)[0], "%Y-%m-%d %H:%M:%S,%f")
except ValueError:
    dt = None

前者取决于日志文件的规则性以及您希望解决方案的速度和健壮性,例如,line.split(" [", 1)[0]很快,但很脆弱。更可靠的解决方案是:

^{pr2}$

但可能会慢一点。在

这是你的正则表达式。我测试了正则表达式,但没有测试完整的代码

def searchLogs(fn, searchPatterns):
    res = []
    with open(fn) as f:
        for lineNo, line in enumerate(f, 1):
            #check if pattern strings exist in line
            for sPattern in searchPatterns:
                if sPattern in line:
                    date = re.search(r'(19|20)\d{2}-(0[1-9]|[12])-(0[1-9]|[12][0-9]|3[01])',line).group()
                    time = re.search(r'\b([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]),[0-9][0-9][0-9]',line).group()
                    fountItem = (fn, pattern, lineNo, date, time, line) # prefer a tuple over list
                    res.append(fountItem)
    return res

PS:REs总是在错误的地方痛苦。如果你需要解释请告诉我。:)

相关问题 更多 >