目標
我正在嘗試制作一個 RegEx,它將從包含記錄內容細微差異的各種 syslog 條目中決議出特定資料。雖然我可以使用多個 RegEx 陳述句來實作我的目標,但如果可能的話,我想將這些陳述句組合成一個單一的合并 RegEx。
日志條目
我遇到的主要問題是某些日志條目的 URL 需要決議為命名組,而其他日志條目沒有任何 URL。下面提供了這兩個不同日志條目的示例。
帶有 URL 的條目
11 月 3 日 11:33:04 host1 postfix/smtpd[12812]:NOQUEUE:拒絕:來自 178.red-83-59-180.dynamicip.rima-tde.net[83.59.180.178] 的 RCPT:554 5.7.1 服務不可用; 使用 b.barracudacentral.org 阻止客戶端主機 [83.59.180.178];http://www.barracudanetworks.com/reputation/?pr=1&ip=83.59.180.178; [email protected] [email protected] proto=ESMTP helo=<178.red-83-59-180.dynamicip.rima-tde.net>
沒有網址的條目
11 月 2 日 16:01:25 host1 postfix/smtpd[31667]:NOQUEUE:reject_warning:來自 mail1.sendersrv.com 的 RCPT[185.3.229.125]:554 5.7.1 服務不可用;使用 bl.spamcop.net 阻止客戶端主機 [185.3.229.125];from=bounces [email protected] [email protected] proto=ESMTP helo=<mail1.sendersrv.com>
正則運算式
在后面的 RegEx 陳述句中,前兩個是我當前用于前面每個日志訊息的內容。第三個 RegEx 是我嘗試將它們合并到一個 RegEx 中,該 RegEx 將決議來自任一日志訊息的資料。我的嘗試是使用一個條件陳述句,它基本上會檢查是否存在,http(s)如果找到,然后將 URL 決議為命名組。如果http(s)未找到,則它將決議所有內容,直到下一個 RegEx 標記。
問題是,當我針對具有 URL 的日志條目測驗 RegEx 時,http(s)盡管將此標記設定為可選(即使用?量詞),RegEx 似乎沒有找到。但是,如果我洗掉?量詞,它會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>. )>. $
我確定問題是我對條件陳述句和?量詞如何作業的誤解。歡迎提出所有建議,并提前感謝您的時間。
uj5u.com熱心網友回復:
您是否嘗試過在regex101 之類的頁面上測驗您的正則運算式?
to=\<(?P<destEm>. )>似乎與您的示例不符。您應該洗掉<>或替換to為helo. 小心讓你的量詞變得懶惰,blkList否則你可能會捕捉到太多的文本。
然后,您可以將您的 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>. ?)\s.*$
uj5u.com熱心網友回復:
一種方法是在第一個正則運算式中替換. https?:\/{2}(?P<entryUrl>. );為(?:. https?:\/{2}(?P<entryUrl>. );)?where?:表示它是一個非捕獲組,?最后表示它是可選的。
然而,它仍然不起作用,因為它. 是貪婪的,所以用惰性. ?代替。
最終正則運算式:
^(?P<datetime>. ?) host1 postfix. ?RCPT from (?P<srcDns>. ?)\[(?P<srcIp>[0-9\.] )\]:. ?blocked using (?P<blkList>. ?);(?:. ?https?:\/{2}(?P<entryUrl>. ?);)?\s. ?\sto=\<(?P<destEm>. ?)>. ?$
https://regex101.com/r/QkmXWz(查看實際效果)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/351507.html
下一篇:洗掉重復項保留最后一次出現
