我正在使用PCRE借助以下正则表达式来匹配异常日志。
正则表达式
\[([\d -:]+)\]ERROR.*?(F:[^ ]+|F:).*?(?sx).*?(\b[a-zA-Z]*Exception\b)
异常日志示例
捕获的异常位于日志语句的内联(在一行中)
[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)
捕获的异常位于任何其他下一条日志语句中
[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 次以上,后跟异常
不使用内联修饰符的另一个选项 s
要使点匹配换行符,可以选择在匹配 ERROR 和 F: 部分后匹配所有不包含 Exception 的行。
^(?!.*\R\[\d)\[([\d :.-]+)]ERROR.*?(F:\S*)(?:(?!.*Exception|.*\R\[\d).*\R)*+.*\b([a-zA-Z]*Exception)\b
关于异常日志的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60609084/