Python如何多次提取日志中两个时间戳间的文本并保留时间戳
提取日志相邻时间戳间的完整文本
需求背景
需要多次提取日志文件中两个相邻时间戳之间的全部文本,日志样例如下:
2022/May/31 14:42:33.775887 blabla. 2022/May/31 14:42:33.775907 abc, id 2 2022/May/31 14:42:33.781586 blabla { one huge block of text } 2022/May/31 14:42:33.781982 def
待处理日志的特征:包含大量时间戳开头的条目,部分日志条目为短行,部分时间戳后会跟随跨多行的大段文本。提取目标是拆分出每一条以时间戳开头的完整日志(含后续跨多行的内容),方便后续对单条日志做修改、分析或丢弃处理。
原有实现的问题
最初尝试的两种方案均存在缺陷,无法满足提取需求:
- 第一种实现代码:
with open(infile) as fp: for result in re.findall("\d{4}/\w{3}/\d{2}(.*?)\}", fp.read(), re.S): print(result)
缺陷:该正则仅在时间戳后存在{...}格式文本块时可正常匹配,若对应时间戳后无该类文本块,正则会持续向后检索直到找到}字符,导致匹配范围跨越后续时间戳,结果错误。运行上述样例时会错误将前三条日志连同文本块一同匹配,遗漏最后一条日志。
- 第二种实现代码:
with open(infile) as fp: for result in re.findall("^\d{4}/\w{3}/\d{2}(.*?)\d{4}/\w{3}/\d{2}", fp.read(), re.S): print(result)
缺陷:该方案运行后无法返回任何匹配结果,无法完成提取。
正确实现方案
以下方案可完美实现提取需求,通过开启re.M多行匹配模式,可正确返回所有携带时间戳的日志条目,包括跨多行的文本块内容:
pattern = r"^\d{4}/\w{3}/\d{2} (\d\d:\d\d:\d\d\.\d+ )(.*(?:\n(?!\d{4}/\w{3}/\d{2}\b).*)*)" with open(infile) as fp: for result in re.findall(pattern, fp.read(), re.M): print(result)
针对上述样例日志,运行后输出结果如下:
['14:42:33.775887 blabla.', '14:42:33.775907 abc, id 2', '14:42:33.781586 blabla {\none\nhuge\nblock\nof\ntext\n}', '14:42:33.781982 def']
内容的提问来源于stack exchange,提问作者FotisK
相关产品推荐
相关产品推荐

