regex - 如何为命名捕获组创建条件正则表达式?

标签 regex conditional-statements named-captures

我们希望将 PMDF 日志转储到 Splunk 中,我正在尝试解析 PMDF SMTP 日志,特别是消息,但我遇到了一个问题,命名捕获组 (dst_channel) 可能有值,也可能没有值。到目前为止,这是我的正则表达式:

\d{2}\-\w{3}\-\d{4}\s\d{2}\:\d{2}\:\d{2}\.\d{2}\s(?P<src_channel>\w+)\s+(?P<dst_channel>\w+)\s(?P<code>\w+)\s(?P<bytes>\d+)\s(?P<from>\w.+)\srfc822

我能够匹配以下消息,其中 tcp_msx_out_2 是 dst_channel

02-Feb-2017 08:00:19.60 tcp_exempt   tcp_msx_out_2 E 2 <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="107d71797c7d717e3d727f657e737563507c7963643e68696a3e737f7d" rel="noreferrer noopener nofollow">[email protected]</a> rfc822;<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3c494f594e7c444546125f5351" rel="noreferrer noopener nofollow">[email protected]</a> <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6613150314261e1f1c4805090b" rel="noreferrer noopener nofollow">[email protected]</a> <<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="315c50585d5c505f1f0004061f000509070105010500051f03080002001f494949714949491f49484b1f525e5c" rel="noreferrer noopener nofollow">[email protected]</a>> pmdf list.xyz.com ([x.x.x.x])

但是,我不匹配以下不包含 dst_channel 值的日志:

02-Feb-2017 09:00:01.59 tcp_imap_int              Q 12 <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1a6262625a62636034797577" rel="noreferrer noopener nofollow">[email protected]</a> rfc822;<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a2d7d1c7d0e2cbcfc3d28fcbccd6c7d0ccc3ce8cdadbd88cc1cdcf" rel="noreferrer noopener nofollow">[email protected]</a> <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="512422342311383c30217f29282b7f323e3c" rel="noreferrer noopener nofollow">[email protected]</a> <6940401380880269855036@PT-D69> pmdf  <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3346405641735a5e52431d4b4a491d505c5e" rel="noreferrer noopener nofollow">[email protected]</a>: smtp;452 4.2.2 Over quota

我的下一个命名捕获组是第一个消息示例中的代码 E,第二个消息示例中的 Q),当 dst_channel 不存在时,正则表达式不会捕获所有代码。

如何修改条件语句的正则表达式,以便如果 dst_channel 存在,它会获取该值,但如果不存在,正则表达式会继续并能够一致地获取我拥有的其他命名捕获组的值?

最佳答案

我建议你使用

\d{2}-\w{3}-\d{4}\s+\d{2}:\d{2}:\d{2}\.\d{2}\s+(?P<src_channel>\w+)(?:\s+(?P<dst_channel>\w+))?\s+(?P<code>\w+)\s+(?P<bytes>\d+)\s+(?P<from>\S+)\s+rfc822
                                                                   ^^^                       ^^  

请参阅regex demo .

基本上,将所有 \s 替换为 \s+,并通过包装 \s+ 和整个 dst 使 dst channel 组可选带有可选非捕获组的 channel 组。

此外,from 组模式应替换为 \S+(除空格之外的一个或多个字符),因为您想要匹配电子邮件,并且 .+ 可能——而且通常确实如此——过度匹配。

关于regex - 如何为命名捕获组创建条件正则表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42007009/

相关文章:

c++ - C+ +'s std::regex have an equivalent to Python' 是否为 re.MULTILINE?

来自 Eloquent Javascript 的 Javascript 递归

ruby - 如何在 ruby​​ 中像 Rubular 一样获取匹配组而不拆分字符串

Java String.replaceAll 带有命名组的反向引用

regex - 如何删除括号之间的字符串

Java RegEx 用于替换开头和结尾部分与特定模式匹配的字符串

regex - 如何在 Scala 中使用正则表达式?

python - 在 Pandas DataFrame 上选择具有条件的列

MySQL - 从选择内部使用条件