UnboundLocalError报错排查:Python正则解析日志文件问题
问题排查与解决方案
1. UnboundLocalError 错误原因及修复
- 错误根源:
lst.append(new)返回的是None,你将这个结果赋值给lst1,但如果正则未匹配到任何内容(比如正则逻辑错误),循环不会执行,lst1从未被定义,导致return lst1触发未定义变量错误。- 即便循环执行,
lst1的值也是None,并非你需要的解析结果列表。
- 修复方式:
直接操作初始化好的lst列表,无需额外的lst1变量,最后返回lst即可。lst在函数开头已定义,无论是否匹配到内容,都能正常返回,不会触发未定义错误。
2. 正则表达式错误修复
原正则存在多处匹配逻辑错误,无法正确解析日志格式,以下是修正后的正则及逻辑说明:
日志行标准结构:host - user_name [time] "request" status size
修正后的正则(启用VERBOSE模式,可忽略正则内的空格):
pattern = r''' (?P<host>\d+\.\d+\.\d+\.\d+) # 匹配IPv4格式的主机地址 \s-\s # 匹配固定分隔符" - " (?P<user_name>\w+|-) # 匹配用户名或匿名符号"-" \s\[ # 匹配" [" (?P<time>[^\]]+) # 匹配[]内的时间内容(直到"]"结束) \]\s" # 匹配"] " (?P<request>[^"]+) # 匹配双引号内的请求内容(直到"结束) " # 匹配闭合双引号 \s\S+\s\S+ # 匹配后续状态码和大小(无需捕获) '''
- 关键修正点:
- 原
host部分最后一段的.未转义,改为\\.\\d+确保匹配IPv4的点分隔符。 user_name原逻辑错误,改为直接匹配用户名(\w+)或匿名符号-。time部分改为匹配[]内所有非]的字符,避免捕获多余的括号和空格。request部分改为匹配双引号内所有非"的字符,确保准确捕获完整请求内容。
- 原
3. 完整修正后的代码
import re def logs(): lst = [] with open("assets/logdata.txt", "r") as file: logdata = file.read() pattern = r''' (?P<host>\d+\.\d+\.\d+\.\d+) \s-\s (?P<user_name>\w+|-) \s\[ (?P<time>[^\]]+) \]\s" (?P<request>[^"]+) "\s\S+\s\S+ ''' for item in re.finditer(pattern, logdata, re.VERBOSE): lst.append(item.groupdict()) return lst # 测试调用示例 result = logs() for entry in result: print(entry)
4. 解析结果示例
运行修正后的代码,解析你提供的日志行,会得到如下格式的字典列表:
[ { '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' }, { 'host': '156.127.178.177', 'user_name': 'okuneva5222', 'time': '21/Jun/2019:15:45:27 -0700', 'request': 'DELETE /interactive/transparent/niches/revolutionize HTTP/1.1' } ]
内容的提问来源于stack exchange,提问作者user20316341
相关产品推荐
相关产品推荐

