使用reg exp分离单行中打印的多个文本日志

2024-10-01 07:42:19 发布

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

我们的程序生成的每个日志具有以下格式:

2021-08-04:12.55.51.965438904: bla bla bla bla

2021-08-04:12.55.51.965493516: bla bla bla bla

2021-08-04:12.55.52.073093436: bla bla bla bla

其中“bla bla”可以是文本/数字的任意组合。在某些情况下,多个日志打印到一行中,如下所示:

2021-08-04:12.55.51.965438904: bla bla bla bla2021-08-04:12.55.51.965493516: bla bla bla bla2021-08-04:12.55.52.073093436: bla bla bla bla

我们如何将每个日志从这样的行中分离出来? 我从这个片段开始

import re

string = "2021-08-04:12.55.51.965438904: bla bla bla bla2021-08-04:12.55.51.965493516: bla bla bla bla2021-08-04:12.55.52.073093436: bla bla bla bla"

reg_exp = re.compile(r"(\d+-\d+-\d+:\d+.\d+.\d+.\d+)")
for match in reg_exp.finditer(string):
    print(match.group(1))

然而,我需要包括“布拉布拉布拉布拉布拉”也。 狙击手只打印时间戳


Tags: in文本import程序reforstring格式
3条回答

这是一种比the original answer I posted更简单的方法。
这一经修订的办法以this commentthe linked SO question为基础

它在每次出现yyyy-mm-dd:或更准确地说\d{4}-\d{2}-\d{2}:时分割字符串。
结果列表在分割开始处有一个额外的空字符串,因此我们使用[1:]忽略它

import re
regex = r"(?=\d{4}-\d{2}-\d{2}:)"
string = "2021-08-04:12.55.51.965438904: bla bla bla bla2021-08-04:12.55.51.965493516: bla bla bla bla2021-08-04:12.55.52.073093436: bla bla bla bla"
for log in re.split(regex, string)[1:]:
    print(log)

我不确定我是否正确地理解了这个问题,因为我看到了一个非常复杂的正则表达式解决方案(我担心我可能是错的),但是为什么不尝试使用re.split,然后将拆分中的每2个元素组合起来呢

类似的东西

import re
from itertools import starmap
from operator import add

string = "2021-08-04:12.55.51.965438904: bla bla bla bla2021-08-04:12.55.51.965493516: bla bla bla bla2021-08-04:12.55.52.073093436: bla bla bla bla"

reg_exp = re.compile(r"(\d+-\d+-\d+:\d+.\d+.\d+.\d+: )")
logs = reg_exp.split(string)
# Group and zip every two elements
logs = zip(logs[1::2], logs[2::2])
# Add elements
logs = starmap(add, logs)
# Cast it to list if necessary, here I don't do it
for log in logs:
    print(log)

印刷品

2021-08-04:12.55.51.965438904: bla bla bla bla
2021-08-04:12.55.51.965493516: bla bla bla bla
2021-08-04:12.55.52.073093436: bla bla bla bla

See this answer instead.

警告

这样做有点代码味道。似乎其中一个日志函数没有在每个日志后打印换行符,而它应该这样做

我建议找到罪魁祸首并从源头解决问题,但在此之前,这应该是可行的

代码

当然,没有正则表达式也可以完成,但我在这里遵循了您的指导,只是在您的代码片段中更改了正则表达式:

import re

string = "2021-08-04:12.55.51.965438904: bla bla bla bla2021-08-04:12.55.51.965493516: bla bla bla bla2021-08-04:12.55.52.073093436: bla bla bla bla"

reg_exp = re.compile(r"(\d{4}-.+?)(?=(\d{4}-|$))")
for match in reg_exp.finditer(string):
    print(match.group(1))

说明

此正则表达式匹配四位数字&;连字符,然后是其他任何内容,直到找到其中一个:另外四个数字&;连字符,或行尾

(\d{4}-.+?)(?=(\d{4}-|$))

下面是在Regex101上测试的表达式的永久链接

更安全的版本*

只需将这些正则表达式粘贴到上面的代码段中即可

(\d{4}-\d{2}-\d{2}:.+?)(?=(\d{4}-\d{2}-\d{2}:|$))

Regex101:这一个检查以确保整个前缀是正确的。它应该看起来像:yyyy-mm-dd:。年、月和日都应该是数字或\d,所以我们得到:\d{4}-\d{2}-\d{2}:

(\d{4}-\d{2}-\d{2}:.+?)(?=(\d{4}-\d{2}-\d{2}:|[\n\r]*$))

Regex101:即使末尾打印了额外的换行符,此项仍将与字符串匹配。它将$更改为[\n\r]*$

如果有人能想出其他方法让regex更安全,请随意添加到这里

*根据OP的要求在下面的评论中添加。

相关问题 更多 >