re.finditer合并正则提取host与user_name无输出问题求助
正则表达式合并后无法匹配的问题解决
单独使用正则提取host或user_name时,代码运行正常并返回正确结果;但将两个正则表达式合并后,使用re.finditer遍历却无法得到任何输出,预期应得到与单独提取一致的结果。
相关代码
import re host = "(?P<host>[\d]{1,3}[.][\d]{1,3}[.][\d]{1,3}[.][\d]{1,3})(?= - )" user_name = " (?P<user_name>((?<= - )[a-zA-Z]+[\d]+)|((?<= - )[-]\s))" time = "(?P<time>(?<=\[).*(?=\]))" request = "(?P<request>POST.*(?=\"))" h_u = host+user_name logdata = """168.95.156.240 - stark2413 [21/Jun/2019:15:45:31 -0700] "GET /engage HTTP/2.0" 201 9645 71.172.239.195 - dooley1853 [21/Jun/2019:15:45:32 -0700] "PUT /cutting-edge HTTP/2.0" 406 24498 180.95.121.94 - mohr6893 [21/Jun/2019:15:45:34 -0700] "PATCH /extensible/reinvent HTTP/1.1" 201 27330 144.23.247.108 - auer7552 [21/Jun/2019:15:45:35 -0700] "POST /extensible/infrastructures/one-to-one/enterprise HTTP/1.1" 100 22921 2.179.103.97 - lind8584 [21/Jun/2019:15:45:36 -0700] "POST /grow/front-end/e-commerce/robust HTTP/2.0" 304 14641 241.114.184.133 - tromp8355 [21/Jun/2019:15:45:37 -0700] "GET /redefine/orchestrate HTTP/1.0" 204 29059""" for item in re.finditer(h_u, logdata): print(item.groupdict())
单独提取host的结果
{'host': '146.204.224.152'} {'host': '197.109.77.178'} {'host': '156.127.178.177'} {'host': '100.32.205.59'} {'host': '168.95.156.240'} {'host': '71.172.239.195'} {'host': '180.95.121.94'}
问题原因
两个正则的预查逻辑冲突:
host使用正向预查(?= - ),仅验证IP后紧跟-但不消耗该字符user_name开头带空格,且用反向预查(?<= - )要求前面是-
合并后,host匹配IP后,-未被消耗,此时user_name需要匹配的位置前是IP的最后一位,不满足反向预查的-要求,导致整体匹配失败。
修复方案
去掉多余的预查逻辑,直接匹配实际存在的连接字符-,将两个正则整合为完整的匹配结构:
import re # 简化后的合并正则 h_u = "(?P<host>[\d]{1,3}(?:\.[\d]{1,3}){3}) - (?P<user_name>[a-zA-Z]+\d+|-\s?)" logdata = """168.95.156.240 - stark2413 [21/Jun/2019:15:45:31 -0700] "GET /engage HTTP/2.0" 201 9645 71.172.239.195 - dooley1853 [21/Jun/2019:15:45:32 -0700] "PUT /cutting-edge HTTP/2.0" 406 24498 180.95.121.94 - mohr6893 [21/Jun/2019:15:45:34 -0700] "PATCH /extensible/reinvent HTTP/1.1" 201 27330 144.23.247.108 - auer7552 [21/Jun/2019:15:45:35 -0700] "POST /extensible/infrastructures/one-to-one/enterprise HTTP/1.1" 100 22921 2.179.103.97 - lind8584 [21/Jun/2019:15:45:36 -0700] "POST /grow/front-end/e-commerce/robust HTTP/2.0" 304 14641 241.114.184.133 - tromp8355 [21/Jun/2019:15:45:37 -0700] "GET /redefine/orchestrate HTTP/1.0" 204 29059""" for item in re.finditer(h_u, logdata): print(item.groupdict())
运行后即可得到包含host和user_name的正确匹配结果:
{'host': '168.95.156.240', 'user_name': 'stark2413'} {'host': '71.172.239.195', 'user_name': 'dooley1853'} {'host': '180.95.121.94', 'user_name': 'mohr6893'} {'host': '144.23.247.108', 'user_name': 'auer7552'} {'host': '2.179.103.97', 'user_name': 'lind8584'} {'host': '241.114.184.133', 'user_name': 'tromp8355'}
内容的提问来源于stack exchange,提问作者Aaryan Kandiah
相关产品推荐
相关产品推荐

