如何通过正则表达式提取日志数据并转换为指定格式的字典列表
Python 正则提取日志字段实现方案
核心思路
你的日志是标准的Apache/Nginx访问日志格式,我们只需要用正则捕获4个目标字段,逐行处理后组装成字典列表即可。
步骤1:正则规则设计
我们使用如下正则表达式,每个分组对应你需要的一个字段:
^(\S+) - (\S+) \[([^\]]+)\] "([^"]+)"
各部分含义:
- 第1个分组
(\S+):匹配开头的IP地址(host字段) - 第2个分组
(\S+):匹配分隔符-后的用户名(user_name字段) - 第3个分组
([^\]]+):匹配中括号[]包裹的时间字符串(time字段) - 第4个分组
([^"]+):匹配双引号""包裹的请求内容(request字段)
步骤2:完整可运行代码
import re # 正则匹配规则预编译,提升处理效率 log_pattern = re.compile(r'^(\S+) - (\S+) \[([^\]]+)\] "([^"]+)"') def parse_log_file(file_path=None, sample_logs=None): result = [] # 优先处理传入的样本日志,也可以传入本地文件路径读取 lines = sample_logs.splitlines() if sample_logs else open(file_path, 'r', encoding='utf-8').readlines() for line in lines: line = line.strip() if not line: continue # 匹配当前行 match = log_pattern.match(line) if match: # 按分组取出对应字段,组装成字典 item = { "host": match.group(1), "user_name": match.group(2), "time": match.group(3), "request": match.group(4) } result.append(item) return result # 测试用样本日志 sample_data = """146.204.224.152 - feest6811 [21/Jun/2019:15:45:24 -0700] "POST /incentivize HTTP/1.1" 302 4622 197.109.77.178 - kertzmann3129 [21/Jun/2019:15:45:25 -0700] "DELETE /virtual/solutions/target/web+services HTTP/2.0" 203 26554 156.127.178.177 - okuneva5222 [21/Jun/2019:15:45:27 -0700] "DELETE /interactive/transparent/niches/revolutionize HTTP/1.1" 416 14701 100.32.205.59 - ortiz8891 [21/Jun/2019:15:45:28 -0700] "PATCH /architectures HTTP/1.0" 204 6048""" # 调用函数,传入样本数据即可得到结果 parsed_logs = parse_log_file(sample_logs=sample_data) # 打印结果查看 for item in parsed_logs: print(item)
运行输出示例
运行后得到的字典列表和你要求的格式完全一致:
[ {"host":"146.204.224.152", "user_name":"feest6811", "time":"21/Jun/2019:15:45:24 -0700", "request":"POST /incentivize HTTP/1.1"}, {"host":"197.109.77.178", "user_name":"kertzmann3129", "time":"21/Jun/2019:15:45:25 -0700", "request":"DELETE /virtual/solutions/target/web+services HTTP/2.0"}, # 剩余条目以此类推 ]
初学者使用说明
- 如果你要读取本地日志文件,只需要把调用的代码改成
parsed_logs = parse_log_file(file_path="你的日志文件路径.log")即可 - 代码已经自动跳过空行、格式不匹配的异常行,不会中途报错终止
内容的提问来源于stack exchange,提问作者Inam Buneri
相关产品推荐
相关产品推荐

