【问题标题】:multiline regex with lookahead带前瞻的多行正则表达式
【发布时间】:2021-11-09 13:03:27
【问题描述】:

我目前正在尝试使用正则表达式读取日志文件。我的日志以时间戳开头,后跟随机多行消息,其中可以包含多个新行、回车和所有类型的字符。

正则表达式应该捕获从时间戳开始的所有内容,即实际的日志消息,直到我们到达新的时间戳。目前,我通过使用积极的前瞻直到下一个时间戳来做到这一点。

在 webside regex101 上,代码或多或少都有效。在我们的安全事件管理器中,相同的正则表达式不起作用。我需要保存每个事件,时间戳是第一个捕获组,日志消息是第二个捕获组。

(\w{3}\s{1}\w{3}\s{1}\d{2}\s{1}\d{2}\:\d{2}\:\d{2}\s{1}\d{4})((\r||.|\n)*)(?=(\w{3}\s{1}\w{3}\s{1}\d{2}\s{1}\d{2}\:\d{2}\:\d{2}\s{1}\d{4}))

示例日志:

2021 年 9 月 14 日星期二 08:57:47 线程 1 推进到日志序列 186(LGWR 开关) 当前日志# 2 seq# 186 mem# 0: D:\ORADB\DV1\REDO02A.LOG 当前日志# 2 seq# 186 mem# 1: H:\ORADB\DV1\REDO02B.LOG 2021 年 9 月 14 日星期二 09:07:40 线程 1 推进到日志序列 187(LGWR 开关) 当前日志# 3 seq# 187 mem# 0: D:\ORADB\DV1\REDO03A.LOG 当前日志# 3 seq# 187 mem# 1: H:\ORADB\DV1\REDO03B.LOG 2021 年 9 月 14 日星期二 09:22:09 线程 1 推进到日志序列 188(LGWR 开关) 当前日志# 4 seq# 188 mem# 0: D:\ORADB\DV1\REDO04A.LOG 当前日志#4 seq#188 mem#1: H:\ORADB\DV1\REDO04B.LOG

regex101

顺便说一句,代码仅在我包含正则表达式的 \r||.|\n“或 null”部分时才有效,我根本不明白。

【问题讨论】:

    标签: regex logging regex-lookarounds flat-file


    【解决方案1】:

    您可以使用[\s\S]* 匹配任何字符,因为\s 用于空格(包括新行),而\S 用于非空格。要使它不跨越整个文本,换句话说,它是非贪婪的,请使用 ? 符号,例如[\s\S]*?试试这个模式:

    (\w{3}\s\w{3}\s\d{2}\s\d{2}:\d{2}:\d{2}\s\d{4})([\s\S]*?)(?=\w{3}\s\w{3}\s\d{2}\s\d{2}:\d{2}:\d{2}\s\d{4}|\Z)
    

    地点:

    • ( - 第一个捕获组的开始
      • \w{3}\s\w{3}\s\d{2}\s - 匹配 Tue Sep 14
      • \d{2}:\d{2}:\d{2}\s\d{4} - 匹配 08:57:47 2021
    • ) - 第一个捕获组结束
    • ( - 第二个捕获组的开始
      • [\s\S]*? - 匹配任何字符,包括换行符。匹配将采用非贪婪方式(因此匹配最少)。
    • ) - 第二个捕获组结束
    • (?= - 前瞻断言的开始
      • \w{3}\s\w{3}\s\d{2}\s\d{2}:\d{2}:\d{2}\s\d{4} - 下一部分必须是时间戳(这与整个正则表达式第一部分中时间戳的匹配模式相同)。
      • | - 或者
      • \Z - 或者下一部分必须是字符串的结尾
    • ) - 前瞻断言结束。请注意,由于在此之前的模式是非贪婪的,因此这将始终是最近的时间戳,因此始终是下一个时间戳。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-13
      • 2020-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-14
      相关资源
      最近更新 更多