抓取正则表达式变量0或1匹配

时间:2014-05-15 21:46:28

标签: python regex

有没有办法引用具有相同名称的2个不同的正则表达式变量?

例如:

log1: 12-3-04: type=type1 event=GET user=thomas access_level=4 ip=1.1.1.1 port=443 dstip=2.2.2.2 dstport=432

log2: 12-3-04: type=type1 event=GET user=brad userdb=Admin ip=1.1.1.1 access_level=2

这两个事件是相同的type但是它们的格式有点不同

正则表达式:

事件普通正则表达式

\d+\-\d+\-\d+\:\s+type=(?P<type>\S+)\s+event\=(?P<event>\S+)\s+user\=(?P<user>\S+)\s+

log1正则表达式:

access_level\=(?P<access_level>\d+)\s+ip\=(?P<\S+>)\s+port\=(?P<\d+>)\s+dstip\=(?P<dstip>\S+)\s+dstport\=(?P<\d+>)

log2正则表达式:

userdb\=(?P<userdb>\S+)\s+ip\=(?P<ip>\S+)\s+access_level\=(?P<access_level>\d+)

因为这些事件类型是相同的,所以我想要1个正则表达式来捕获这两个事件。 我的想法是

(common regex) + (log1 regex)? + (log2 regex)?

这会捕获两个事件但是必须以不同方式命名常见的变量名称。例如access_level。我希望能够引用access_level并让逻辑自动知道我想要哪个access_level

\d+\-\d+\-\d+\:\s+type=(?P<type>\S+)\s+event\=(?P<event>\S+)\s+user\=(?P<user>\S+)\s+(access_level\=(?P<access_level>\d+)\s+ip\=(?P<\S+>)\s+port\=(?P<\d+>)\s+dstip\=(?P<dstip>\S+)\s+dstport\=(?P<\d+>))?(userdb\=(?P<userdb>\S+)\s+ip\=(?P<ip>\S+)\s+access_level\=(?P<access_level>\d+))?

2 个答案:

答案 0 :(得分:2)

我不认为这是可能的。一个小功能可以完成工作并且更容易阅读。

def parse_log_line(line):
    name, date, *pairs = line.split(" ")
    name = name.rstrip(":")
    date = date.rstrip(":")
    data = dict(pair.split("=", 2) for pair in pairs)
    return (name, date, data)

a = "log1: 12-3-04: type=type1 event=GET user=thomas access_level=4 ip=1.1.1.1 port=443 dstip=2.2.2.2 dstport=432"
b = "log2: 12-3-04: type=type1 event=GET user=brad userdb=Admin ip=1.1.1.1 access_level=2"

print(parse_log_line(a)[2]["access_level"])
print(parse_log_line(b)[2]["access_level"])

答案 1 :(得分:1)

这样的事情:

(常见的regexp)+(access_level之前的log 2的一部分)? +(access_level regexp)+(access_level之后的日志1的一部分)?

E.g:

\d+\-\d+\-\d+\:\s+type=(?P<type>\S+)\s+event\=(?P<event>\S+)\s+user\=(?P<user>\S+)\s+(userdb\=(?P<userdb>\S+)\s+ip\=(?P<ip>\S+)\s+)?access_level\=(?P<access_level>\d+)(\s+ip\=(?P<ip2>\S+)\s+port\=(?P<port>\d+)\s+dstip\=(?P<dstip>\S+)\s+dstport\=(?P<dstport>\d+))?

请仔细测试: - )

我发现这只适用于access_level而不适用于ip。