【发布时间】:2021-11-07 00:44:18
【问题描述】:
目标
我正在尝试制作一个 RegEx,它将从各种 syslog 条目中解析出特定数据,这些条目包含记录内容的细微差异。虽然我可以使用多个 RegEx 语句来实现我的目标,但如果可能的话,我想将这些语句组合成一个统一的 RegEx。
日志条目
我遇到的主要问题是一些日志条目有一个需要解析为命名组的 URL,而其他日志条目没有任何 URL。下面提供了这两个不同日志条目的示例。
使用 URL 输入
Nov 3 11:33:04 host1 postfix/smtpd[12812]: NOQUEUE: reject: RCPT from 178.red-83-59-180.dynamicip.rima-tde.net[83.59.180.178]: 554 5.7.1 Service unavailable; Client host [83.59.180.178] blocked using b.barracudacentral.org; http://www.barracudanetworks.com/reputation/?pr=1&ip=83.59.180.178; from=<lmclapp68@newmail.spamcop.net> to=<user1@example.com> proto=ESMTP helo=<178.red-83-59-180.dynamicip.rima-tde.net>
没有网址的条目
Nov 2 16:01:25 host1 postfix/smtpd[31667]: NOQUEUE: reject_warning: RCPT from mail1.sendersrv.com[185.3.229.125]: 554 5.7.1 Service unavailable; Client host [185.3.229.125] blocked using bl.spamcop.net; from=<bounces+rL59wUXq98_inBrG@sendersrv.com> to=<user1@example.com> proto=ESMTP helo=<mail1.sendersrv.com>
正则表达式
在随后的 RegEx 语句中,前两个是我目前用于前面每条日志消息的语句。第三个 RegEx 是我尝试将它们合并到一个 RegEx 中,该 RegEx 将解析来自任一日志消息的数据。我的尝试是使用一个条件语句,它基本上会检查http(s) 是否存在,如果找到,则将 URL 解析为命名组。如果没有找到http(s),那么它将解析出所有内容,直到下一个 RegEx 令牌。
问题是,当我针对具有 URL 的日志条目测试 RegEx 时,RegEx 似乎没有找到 http(s),尽管此标记被设置为可选(即使用 ? 量词)。但是,如果我删除 ? 量词,它确实会找到 http(s),然后根据需要解析 URL。但是,如果没有量词,RegEx 无法处理没有 URL 的日志条目。
使用 URL 解析条目
^(?P<datetime>.+) host1 postfix.+RCPT from (?P<srcDns>.+)\[(?P<srcIp>[0-9\.]+)\]:.+blocked using (?P<blkList>.+);.+https?:\/{2}(?P<entryUrl>.+);\s.+\sto=\<(?P<destEm>.+)>.+$
解析没有 URL 的条目
^(?P<datetime>.+) host1 postfix.+RCPT from (?P<srcDns>.+)\[(?P<srcIp>[0-9\.]+)\]:.+blocked using (?P<blkList>.+);\s.+\sto=\<(?P<destEm>.+)>.+$
尝试合并 RegEx
^(?P<datetime>.+) host1 postfix.+RCPT from (?P<srcDns>.+)\[(?P<srcIp>[0-9\.]+)\]:.+blocked using (?P<blkList>.+)(?<=[a-z]);.+(https?:\/{2})?(?(5)(?P<entryUrl>.+)|.+)to=\<(?P<destEm>.+)>.+$
我确定问题在于我对条件语句和 ? 量词如何工作的误解。
【问题讨论】:
标签: regex regex-group