Как я могу создать условное регулярное выражение для именованной группы захвата?

Мы стремимся выгружать наши журналы PMDF в Splunk, и я пытаюсь проанализировать SMTP-журналы PMDF, в частности сообщение, и я сталкиваюсь с проблемой, когда именованная группа захвата (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 mailman-bounces@list.xyz.com rfc822;user@xyz.com user@xyz.com <mailman.157.1486040414.29131.xxx@xxx.xyz.com> pmdf list.xyz.com ([x.x.x.x])

однако я не сопоставляю следующие журналы, которые не содержат значение dst_channel:

02-Feb-2017 09:00:01.59 tcp_imap_int              Q 12 xxx@xyz.com rfc822;user@imap-internal.xyz.com user@imap.xyz.com <6940401380880269855036@PT-D69> pmdf  user@imap.xyz.com: smtp;452 4.2.2 Over quota

Следующая названная группа захвата - это код E в первом примере сообщения и Q во втором), и когда dst_channel отсутствует, регулярное выражение не захватывает все коды.

Как я могу изменить свое регулярное выражение для условных операторов, чтобы при наличии dst_channel оно получало значение, а если нет - регулярное выражение продолжалось и могло последовательно получать значения для других именованных групп захвата, которые у меня есть?

2 ответа

Решение

Я предлагаю вам использовать

\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
                                                                   ^^^                       ^^  

Смотрите демо-версию регулярного выражения.

В основном, заменить все \s с \s+ и сделать группу каналов DST необязательной, оборачивая оба \s+ и вся группа каналов DST с необязательной группой без захвата.

Так же from шаблон группы должен быть заменен на \S+ (один или несколько символов кроме пробела), потому что вы хотите сопоставить электронную почту, и .+ может - и, как правило, это - превзойти.

Это сработало, если я изменил \w+ к \w*

\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

Вы можете проверить это здесь

Другие вопросы по тегам