我设计正则表达式以匹配异常消息字段。
^.*\s([^:,\s]+):\s+([^:]+)\sat\s+\S+\((\w+)\.\w+:(\d+)\)$
它只匹配几个字段。
测试字符串是:
ERROR java.lang.NullPointerException: Sample Java Logback Exception
at Sample.errorLevel3(Sample.java:35)
at Sample.errorLevel4(Sample.java:34)
at Sample.errorLevel5(Sample.java:30)
at Sample.errorLevel6(Sample.java:3)
找到匹配项:
java.lang.NullPointerException
Sample Java Logback Exception
Sample
35
预期比赛:
java.lang.NullPointerException
Sample Java Logback Exception
Sample.errorLevel3
Sample.java
35
Sample.errorLevel4
Sample.java
34
Sample.errorLevel5
Sample.java
30
Sample.errorLevel6
Sample.java
3
任何人都有更好的正则表达式来匹配异常消息的字段吗?
答案 0 :(得分:1)
每当您使用()时,您都会创建一个捕获组。因此,在正则表达式中,您有4个捕获组,您可以从中提取数据。
第一个捕获异常名称,我相信它是正确的,但我不知道所有的可能性。
第二个捕获消息。我认为它应该是可选的,所有例外都有消息?包括定制的?除此之外,它似乎是正确的。我只会添加$ after以确保它达到行尾。
问题始于应该捕获方法名称的第三个捕获组,我相信。更改此部分:\S+\((\w+)\.\w+:(\d+)\)$
至([\w.]+\w+)\(([\w.]+\w+)\:(\d+)\)$
添加的3个捕获组用于方法名称,文件名和行号。
此外,添加额外的+以允许您捕获多个错误行
最终的正则表达式为:^.*\s([^:,\s]+):\s+([^:]+)$(?:\s*at\s+([\w\.]+\w+)\(([\w\.]+\w+)\:(\d+)\))+
但是,正如Doro所指出的那样,您无法使用相同的正则表达式捕获多个部分匹配项,这就是您尝试对错误行进行的操作。
您应该分为2个正则表达式:^.*\s([^:,\s]+):\s+([^:]+)$
和\s*at\s+([\w\.]+\w+)\(([\w\.]+\w+)\:(\d+)\)+
除此之外,我还不确定java正则表达式,但在C#中我们可以命名捕获组,以便您以后可以使用(?your group here)语法轻松获取它们。我将在Java中搜索它是如何完成的并在此处发布。
编辑:要了解Java如何支持命名组,请参阅this answer。
您可以测试正则表达式的好网站是regex101.com。
答案 1 :(得分:1)
您可以匹配第一行,然后使用\G assertion
匹配以下行:
<强>正则表达式强>
(?:^.*\s([^:,\s]+):\s+([^:\n]+)|\G(?!\A))\s*at\s+(\S+)\((\w+\.\w+):(\d+)\)$
其中:
^.*\s([^:,\s]+):\s+([^:\n]+)
例外说明\G(?!\A)
上一场比赛结束\s*at\s+
文字at
被空格包围(包括换行符)(\S+)
第3组中的错误级别\((\w+\.\w+)
第4组中的来源:(\d+)\)$
第5组中的第<强>代码强>
String text = String.join("\n",
"ERROR java.lang.NullPointerException: Sample Java Logback Exception",
"at Sample.errorLevel3(Sample.java:35)",
"at Sample.errorLevel4(Sample.java:34)",
"at Sample.errorLevel5(Sample.java:30)",
"at Sample.errorLevel6(Sample.java:3)"
);
String pattern = "(?:^.*\\s([^:,\\s]+):\\s+([^:\\n]+)|\\G(?!\\A))\\s*at\\s+(\\S+)\\((\\w+\\.\\w+):(\\d+)\\)$";
Pattern regex = Pattern.compile(pattern, Pattern.MULTILINE);
Matcher m = regex.matcher(text);
int matchNum = 0;
//Loop matches
while (m.find())
{
matchNum++;
// Loop groups
for (int i = 1; i <= m.groupCount(); i++)
{
if (m.group(i) != null) {
System.out.println("Match " + matchNum + " - Group " + i + ": " + m.group(i));
}
}
}
<强>输出强>
Match 1 - Group 1: java.lang.NullPointerException
Match 1 - Group 2: Sample Java Logback Exception
Match 1 - Group 3: Sample.errorLevel3
Match 1 - Group 4: Sample.java
Match 1 - Group 5: 35
Match 2 - Group 3: Sample.errorLevel4
Match 2 - Group 4: Sample.java
Match 2 - Group 5: 34
Match 3 - Group 3: Sample.errorLevel5
Match 3 - Group 4: Sample.java
Match 3 - Group 5: 30
Match 4 - Group 3: Sample.errorLevel6
Match 4 - Group 4: Sample.java
Match 4 - Group 5: 3
答案 2 :(得分:0)
您无法使用正则表达式进行动态匹配。你的目标必须分两步完成。
第1步 - 提取错误标题:
ERROR ([^:]+): (.*)
https://regex101.com/r/eQ3rI5/1
第2步 - 提取错误信息
(?:\s+at ([^(]+)\(([^:]+):(\d+))\)