【问题标题】:Regex for exception logs异常日志的正则表达式
【发布时间】:2020-03-09 22:18:08
【问题描述】:

我正在使用PCRE 在以下正则表达式的帮助下匹配异常日志。

正则表达式

\[([\d -:]+)\]ERROR.*?(F:[^ ]+|F:).*?(?sx).*?(\b[a-zA-Z]*Exception\b)

异常日志示例

  1. 捕获的异常在日志语句的内联(在一行中)

    [2020-03-07 01:02:37.512]ERROR [L:xx F:yy T:zz R: C: ] xxxxxxx xxxxx xxxx xxxx NullPointerException
            at com.package.name(b.java:20)
            at com.package.name.someClass.someMethod(P.java:2423)
            at com.package.name.someClass.someMethod(P.java:40)
            at com.package.name.someClass.someMethod(P.java:4054)
    
  2. 捕获的异常在任何其他下一个日志语句中

    [2020-03-07 01:02:37.512]ERROR [L:xx F:yy T:zz R: C: ] xxxxxxx xxxxx xxxx xxxxxxxx xxxxxxxxxxxxxxxx 
    xxxxxxxxx xxxxxxxxxxx xxxxxxxx xxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxx
    xxxxxxxx xxxx NullPointerException
            at com.package.name(b.java:20)
            at com.package.name.someClass.someMethod(P.java:2423)
            at com.package.name.someClass.someMethod(P.java:40)
            at com.package.name.someClass.someMethod(P.java:4054)
    

第二个样本与上述正则表达式不匹配。

我也尝试使用multi-line flag (\m),但它不会因为它不应该匹配任何东西而停止

示例

[2020-03-07 01:02:37.512]ERROR [L:xx F:yy1 T:zz1 R: C: ] xxxxxxx xxxxx xxxx xxxx
[2020-03-07 01:03:37.512]ERROR [L:xx F:yy2 T:zz2 R: C: ] xxxxxxx xxxxx xxxx xxxx
[2020-03-07 01:04:37.512]ERROR [L:xx F:yy3 T:zz3 R: C: ] xxxxxxx xxxxx xxxx xxxx 
[2020-03-07 01:05:37.512]ERROR [L:xx F:yy4 T:zz5 R: C: ] NullPointerException
            at com.package.name(b.java:20)
            at com.package.name.someClass.someMethod(P.java:2423)
            at com.package.name.someClass.someMethod(P.java:40)
            at com.package.name.someClass.someMethod(P.java:4054)

预期结果

第一组:2020-03-07 01:05:37.512, 第 2 组:F:yy4, 第 3 组:NullPointerException

实际结果

第一组:2020-03-07 01:02:37.512 第 2 组:F:yy1 第 3 组:NullPointerException

看看匹配第一行后它是如何在找到完整的表达式之前停止的。

谁能帮帮我。

【问题讨论】:

    标签: regex parsing logging pcre


    【解决方案1】:

    您可以从模式的开头检查下一行不以例如[ 开头的数字,以及使用负前瞻(?!.*\R\[\d) 的数字,因为之后您使用内联修饰符(?sx)

    这部分 (F:[^ ]+|F:) 可以缩短为匹配 F: 和 0+ 次非空白字符 (F:\S*)

    在字符类[\d -:] 中,连字符匹配一个范围,而不仅仅是一个连字符。如果您要按字面意思匹配,例如可以将其移到末尾并添加匹配点。

    ^(?!.*\R\[\d)\[([\d :.-]+)]ERROR.*?(F:\S*)(?sx).*?\b([a-zA-Z]*Exception)\b
    

    说明

    • ^ 字符串开始
    • (?!.*\R\[\d) 否定前瞻,断言下一行不以 [\R 匹配 unicode 换行序列的数字开头
    • \[匹配[
    • ([\d :.-]+) 捕获组 1,匹配任何列出的
    • ]匹配]
    • ERROR.*? 匹配 ERROR 和 0+ 次除换行符以外的任何字符
    • (F:\S*) 捕获第 2 组,匹配 F: 和 0+ 次非空白字符
    • (?sx).*? 内联修饰符 s 使点匹配换行符,x 忽略空格
    • \b([a-zA-Z]*Exception)\b 捕获第 3 组,匹配 0+ 次字符 a-zA-Z 后跟异常

    Regex demo

    不使用内联修饰符s 使点与换行符匹配的另一个选项可能是在匹配 ERROR 和 F: 部分后选择性地匹配所有不包含 Exception 的行。

    ^(?!.*\R\[\d)\[([\d :.-]+)]ERROR.*?(F:\S*)(?:(?!.*Exception|.*\R\[\d).*\R)*+.*\b([a-zA-Z]*Exception)\b
    

    Regex demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-09
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      • 2020-06-25
      相关资源
      最近更新 更多