异常日志的正则表达式

标签 regex parsing logging pcre

我正在使用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)

预期结果

Group 1: 2020-03-07 01:05:37.512, Group 2: F:yy4, Group 3: NullPointerException

实际结果

Group 1: 2020-03-07 01:02:37.512 Group 2: F:yy1 Group 3: NullPointerException

看看在匹配第一行后它如何不会停止,直到找到完整的表达式。

有人可以帮我吗?

最佳答案

您可以从模式的开头检查下一行是否不以 [ 开头。和使用负前瞻的数字 (?!.*\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,匹配字符 a-zA-Z 0 次以上,后跟异常

Regex demo

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

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

Regex demo

关于异常日志的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60609084/

相关文章:

regex - 不能在 awk 命令中使用 "("

python - 在 python 中使用正则表达式返回唯一匹配项

C++ int 和带分隔符的字符串解析

c# - 使用 nLog 丢失日志和不一致的存档从多个进程进行日志记录

javascript - 通话结束时的事件/JavaScript

javascript - 从句子中删除停用词

java - Java 的正则表达式模式分类?

java - 如何使用 JAVA 中的 DOM 解析器解析一个 XML 文件,其中有两个不同的事务具有所有相同的子标签,但一个标签不同?

c# - 使用正则表达式解析多个XML标签

c# - 在 ASP.NET Core 中分离应用程序级日志记录和框架级日志记录