Skip to main content
 首页 » 编程设计

python之在 Python 中解析大型伪 csv 日志文件

2025年05月04日10kevingrace

我有几个非常大的非 csv 日志文件。

给定以下条件:

  1. 值字段有未转义的换行符和逗号,几乎任何内容都可以在值字段中,包括'='
  2. 每个有效行都有未知数量的有效值字段
  3. 有效值类似于 key=value这样一个有效的行看起来像 key1=value1, key2=value2, key3=value3等
  4. 每个有效行的开头应以eventId=<some number>, 开头

读取文件、将文件拆分为正确的行然后将每一行解析为正确的键值对的最佳方法是什么?

我试过了

file_name = 'file.txt' 
read_file = open(file_name, 'r').read().split(',\neventId') 

这会正确解析第一个条目,但所有其他条目都以 =# 开头而不是 eventId=# .有没有办法在有效的换行符上保留分隔符和拆分?

另外,速度也很重要。

示例数据:

eventId=123, key=value, key2=value2: 
this, will, be, a problem, 
maybe?=, 
anotherkey=anothervalue, 
eventId=1234, key1=value1, key2=value2, key3=value3, 
eventId=12345, key1= 
msg= {this is not a valid key value pair}, key=value, key21=value=, 

是的,文件真的很乱(有时)这里的每个事件都有 3 个键值对,尽管实际上每个事件中的键值对数量未知。

请您参考如下方法:

这个问题很疯狂,但这里有一个似乎可行的解决方案。 children ,总是使用现有的库来输出格式化数据。

import re; 
 
in_string = """eventId=123, goodkey=goodvalue, key2=somestuff: 
this, will, be, a problem, 
maybe?=, 
anotherkey=anothervalue, gotit=see, 
the problem===s, 
eventId=1234, key1=value1, key2=value2, key3=value3, 
eventId=12345, key1= 
msg= {this is not a valid key value pair}, validkey=validvalue,""" 
 
line_matches = list(re.finditer(r'(,\n)?eventId=\d', in_string)) 
 
lines = [] 
for i in range(len(line_matches)): 
    match_start = line_matches[i].start() 
    next_match_start = line_matches[i+1].start() if i < len(line_matches)-1 else len(in_string)-1 
    line = in_string[match_start:next_match_start].lstrip(',\n') 
    lines.append(line) 
 
lineDicts = [] 
for line in lines: 
    d = {} 
    pad_line = ', '+line 
    matches = list(re.finditer(r', [\w\d]+=', pad_line)) 
    for i in range(len(matches)): 
        match = matches[i] 
        key = match.group().lstrip(', ').rstrip('=') 
        next_match_start = matches[i+1].start() if i < len(matches)-1 else len(pad_line) 
        value = pad_line[match.end():next_match_start] 
        d[key] = value 
    lineDicts.append(d) 
 
print lineDicts 

输出 [{'eventId': '123', 'key2': 'somestuff:\nthis, will, be, a problem,\nmaybe?=,\nanotherkey=anothervalue', 'goodkey': ' goodvalue', 'gotit': 'see,\nthe problem===s'}, {'eventId': '1234', 'key2': 'value2', 'key1': 'value1', 'key3': ' value3'}, {'eventId': '12345', 'key1': '\nmsg= {这不是有效的键值对}', 'validkey': 'validvalue'}]