Как я могу создать условное регулярное выражение для именованной группы захвата?
Мы стремимся выгружать наши журналы 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
Вы можете проверить это здесь