Python正则匹配日志时跳过用户名为-的行及host前置空格问题求解
问题原因分析
- 第一个问题(跳过用户名是
-的第二行):你当前正则中user_name分组的匹配规则是\w.*,\w只能匹配大小写字母、数字和下划线,无法匹配半角减号-,当第二行用户名为-时匹配失败,整行被跳过。 - 第二个问题(host字段带前置空格):
- 你定义的
logdata中第二、第三行日志开头带有缩进空白,而host分组的匹配规则.*是贪婪匹配,会将行首的缩进空白也纳入匹配结果 - 你没有开启多行匹配模式,也没有限制
host的匹配规则,导致匹配范围不受控
- 你定义的
- 额外隐藏问题:你编写的正则存在语法疏漏(
(\]\ \"缺少闭合右括号),同时re.VERBOSE模式会忽略正则中的空白和注释,你当前的正则拆分方式也会导致匹配逻辑不符合预期。
修复后的代码
import re def logs(): logdata = """146.204.224.152 - feest6811 [21/Jun/2019:15:45:24 -0700] "POST /incentivize HTTP/1.1" 302 4622 159.253.153.40 - - [21/Jun/2019:15:46:10 -0700] "POST /e-business HTTP/1.0" 504 19845 197.109.77.178 - kertzmann3129 [21/Jun/2019:15:45:25 -0700] "DELETE /virtual/solutions/target/web+services HTTP/2.0" 203 26554""" # 修正后的正则,支持匹配-作为用户名,忽略行首空白,限制各字段匹配范围 pattern = r""" ^\s* # 匹配行首可选的空白字符,提前过滤掉缩进 (?P<host>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) # 匹配IPv4地址格式 \s-\s # 匹配固定分隔符 空格-空格 (?P<user_name>[^\s]+) # 匹配非空白字符,支持-作为用户名 \s\[ # 匹配到时间前的分隔符 (?P<time>[^\]]+) # 匹配到]之前的所有内容作为时间 \]\s" # 匹配时间后到请求前的分隔符 (?P<request>[^"]+) # 匹配到"之前的所有内容作为请求 " # 匹配请求结束的引号 """ result = [] for item in re.finditer(pattern, logdata, re.VERBOSE | re.MULTILINE): result.append(item.groupdict()) return result # 测试输出 for entry in logs(): print(entry)
运行输出
{'host': '146.204.224.152', 'user_name': 'feest6811', 'time': '21/Jun/2019:15:45:24 -0700', 'request': 'POST /incentivize HTTP/1.1'} {'host': '159.253.153.40', 'user_name': '-', 'time': '21/Jun/2019:15:46:10 -0700', 'request': 'POST /e-business HTTP/1.0'} {'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'}
内容的提问来源于stack exchange,提问作者Saeed Majidaie
相关产品推荐
相关产品推荐

