【问题标题】:Regex multiline log正则表达式多行日志
【发布时间】:2019-02-09 04:25:39
【问题描述】:

我想使用 .NET / Powershell 正则表达式在日志中搜索特定位置的 Success 状态,例如 ABC

如果我使用以下模式:"(?ms)A status: Success.*?Location: " 和全局(又名 AllMatches),那么它会在任何位置找到状态为 Success 的所有日志记录。

如果我尝试通过将ABC 附加到模式来缩小范围,那么匹配太贪心了,从第 18 行的 Success 一直到第 28 行的 ABC

我放弃并使用了更明确的模式(它获取完整的日志记录并且似乎可以工作,因为我在 Success 和 Location 之间指定了一个模式):

(?sm)^\d([ \S]*\s{10}){3}A status: Success\s{2}([ \S]*\s{10}){2}Location: ABC[ \S]*

有没有更简单的模式可以找到我想要的东西?

注意:我不介意模式是否抓取从日期时间(含)到日期时间(不含)的完整日志记录,

日志文件:

04/09/2018 06:31:59 AM [class | Info] some message received from 101592 (123.123.123.124)
        Request Id: 0 (Descriptor: 0, Operator Request Id: 0)
        A type: bar
        A status: Queued
        The id: 1E25
        Additional info: Inserted in queue at position 1 on device ABC
        Location: ABC, subarea: 2
04/09/2018 06:31:59 AM [class | Info] some message received from 102364 (123.123.123.123)
        Request Id: 0 (Descriptor: 0, Operator Request Id: 0)
        A type: bar
        A status: Queued
        The id: 1E25
        Additional info: Inserted in queue at position 1 on device ABC
        Location: ABC, subarea: 2
04/09/2018 06:31:59 AM [class | Info] some message received from 102364 (123.123.123.123)
        Request Id: 0 (Descriptor: 0, Operator Request Id: 0)
        A type: blah bit foo
        A status: Success
        The id: T908
        Additional info: 
        Location: DEF, subarea: 3
04/09/2018 06:32:00 AM [class | Info] some message received from 102364 (123.123.123.123)
        Request Id: 0 (Descriptor: 0, Operator Request Id: 0)
        A type: bar
        A status: Success
        The id: DG08
        Additional info: 
        Location: ABC, subarea: 1

【问题讨论】:

  • single regex 方法在这里相当麻烦。
  • 使用Get-Content -Raw读取文件,在"(?m)^(?=\d{2}/\d{2}/\d{4})"分割成块,并反复使用Where-ObjectSelect-String过滤你想要的块。

标签: .net regex powershell


【解决方案1】:

尝试以下任何一种:

(?m)A status: Success(?:\n\h+.+)+Location: ABC

(?m)A status: Success(?:\n\s+.+)+Location: ABC(如果不支持\h

Demo1

Demo2

解释

只需限制处理额外数据的方式即可。而不是.*?,只需使用(?:\n\h+[^\n]+)+(即新行+开头的一些空格)这将不允许通过下一个日志条目,因为日期从行首开始。

(注意:我删除了 s 修饰符)

【讨论】:

  • 只有在所需的日志条目是最后一个条目时,您的正则表达式才有效。
  • @SebastianProske 完全正确。现在应该修好了。谢谢!!
  • 我认为 .NET 不支持 \h(水平空格)转义字符,但其他都可以。
  • 它可以通过\s 进行更改,我只是使用\h 来更安全。我会修改答案。
【解决方案2】:

试试这个模式:^\d{2}\/(.++\n){3}(?=.+Success)(.++\n){3}(?=.+ABC).++

我开始匹配,如果在行首有两位数字后跟/^\d{2}\/

然后,我匹配三行,进入status行:(.++\n){3},我使用所有格量词避免回溯。

如果Success 出现在当前行上,我匹配接下来的三行(我用肯定的前瞻检查):(?=.+Success)(.++\n){3}

然后我匹配最后一行,如果该行中有ABC(?=.+ABC).++

Demo

【讨论】:

    猜你喜欢
    • 2021-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    相关资源
    最近更新 更多