准确读取不一致的文本文件结构
Reading non-consistent textfile structure accurately
我目前正在尝试解析日志,但我 运行 遇到一个解析条目超过一行的问题,正常的条目如下所示:
23/09/2020, 11:14 - Serial Num: Random Text
我从这里解析日期:
dates = [x.strftime('%x %X') for x in datefinder.find_dates(t_str)]
然后我有这个非常简陋的正则表达式,我用它来捕获分号之后的文本(当它出现时,因为它也不总是一致的):
pattern1 = "\- (.*?)\:"
y = re.search(pattern1, x).group(1)
我最大的问题是日志中的某些条目在移动到新条目之前会持续一段时间:
23/09/2020, 11:14 - Serial Num: Random Text etc.... for 6 new lines
我更习惯 pandas 并将其放入 read_csv()
或进行简单的逐行阅读,所以我有点迷茫,感谢您的帮助!
编辑:澄清一下,每个新行并不总是以日期开头,所以我目前正在制作条件解析器,但有点困难。
编辑:我已将此解决方案稍微修改到我想要的位置,但它适用于我的特定用例,如果其他人需要采用它,则不应涉及太多更改。我已将其重写为可重用性的函数
def LogText_Transformer(in_path, out_text_path, out_csv_path):
"""
:param in_path: File path in, as txt file
:param out_text_path: intermediary Out path formatted txt file
:param out_csv_path: Out path for written file as csv
:return: Formatted log as csv
"""
rx = "(\d{2}/\d{2}/\d{4}, \d{2}:\d{2})(.*?)(?=\d{2}/\d{2}/\d{4}, \d{2}:\d{2}|$)"
with open(in_path + '.txt', 'r') as f, open(out_text_path + '.txt', 'w') as fo:
for line in f:
if not line.isspace():
fo.write(line)
with open(out_text_path + '.txt', 'r') as file:
data = file.read().rstrip()
results = re.findall(rx, data, re.DOTALL)
new_file = open(out_csv_path + '.csv', 'w+', newline='')
with new_file:
write = csv.writer(new_file)
write.writerows(results)
核心代码片段是前两个 open()
调用,结合 re.DOTALL
参数很好地解决了这个问题。不是最优雅的,但它有效!
我目前正在尝试解析日志,但我 运行 遇到一个解析条目超过一行的问题,正常的条目如下所示:
23/09/2020, 11:14 - Serial Num: Random Text
我从这里解析日期:
dates = [x.strftime('%x %X') for x in datefinder.find_dates(t_str)]
然后我有这个非常简陋的正则表达式,我用它来捕获分号之后的文本(当它出现时,因为它也不总是一致的):
pattern1 = "\- (.*?)\:"
y = re.search(pattern1, x).group(1)
我最大的问题是日志中的某些条目在移动到新条目之前会持续一段时间:
23/09/2020, 11:14 - Serial Num: Random Text etc.... for 6 new lines
我更习惯 pandas 并将其放入 read_csv()
或进行简单的逐行阅读,所以我有点迷茫,感谢您的帮助!
编辑:澄清一下,每个新行并不总是以日期开头,所以我目前正在制作条件解析器,但有点困难。
编辑:我已将此解决方案稍微修改到我想要的位置,但它适用于我的特定用例,如果其他人需要采用它,则不应涉及太多更改。我已将其重写为可重用性的函数
def LogText_Transformer(in_path, out_text_path, out_csv_path):
"""
:param in_path: File path in, as txt file
:param out_text_path: intermediary Out path formatted txt file
:param out_csv_path: Out path for written file as csv
:return: Formatted log as csv
"""
rx = "(\d{2}/\d{2}/\d{4}, \d{2}:\d{2})(.*?)(?=\d{2}/\d{2}/\d{4}, \d{2}:\d{2}|$)"
with open(in_path + '.txt', 'r') as f, open(out_text_path + '.txt', 'w') as fo:
for line in f:
if not line.isspace():
fo.write(line)
with open(out_text_path + '.txt', 'r') as file:
data = file.read().rstrip()
results = re.findall(rx, data, re.DOTALL)
new_file = open(out_csv_path + '.csv', 'w+', newline='')
with new_file:
write = csv.writer(new_file)
write.writerows(results)
核心代码片段是前两个 open()
调用,结合 re.DOTALL
参数很好地解决了这个问题。不是最优雅的,但它有效!