Java 用于提取异常消息字段的正则表达式
我设计了正则表达式来匹配异常消息字段Java 用于提取异常消息字段的正则表达式,java,regex,Java,Regex,我设计了正则表达式来匹配异常消息字段 ^.*\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 Sampl
^.*\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
有谁有更好的正则表达式来匹配异常消息的字段吗?您不能有与正则表达式匹配的动态数目。你的目标必须在两步之内实现 步骤1-提取错误标题:
ERROR ([^:]+): (.*)
步骤2-提取错误信息
(?:\s+at ([^(]+)\(([^:]+):(\d+))\)
任何时候使用()都会创建一个捕获组。因此,在正则表达式中,您有4个捕获组,从中可以提取数据
第一个捕获了异常名称,我相信它是正确的,尽管我不知道所有的可能性
第二个捕获消息。我认为它应该是可选的,所有的异常都有消息吗?包括定制的吗?除此之外,这似乎是正确的。我只会在后面加上一美元,以确保它到达终点
我认为,问题始于第三个捕获组,它应该捕获方法名称。将此部分:\S+\(\w+)\。\w+:(\d+)$
更改为([\w.]+\w+)\([\w.]+\w+:(\d+)$
添加的3个捕获组用于方法名、文件名和行号
另外,添加一个+以允许您捕获多个错误行
最后一个正则表达式是:^.*\s([^:,\s]+):\s+([^:]+)$(?:\s*at\s+([\w\.]+\w+)([\w\.]+\w+:(\d+)+
然而,正如Doro所指出的,您不能用同一个正则表达式捕获多个部分匹配,这就是您试图使用错误行所做的
您应该分成两个正则表达式:^..*\s([^:,\s]+):\s+([^:]+)$
和\s*at\s+([\w\.]+\w+)([\w\.]+\w+):(\d+)+
除此之外,我不确定java正则表达式是否正确,但在C#中,我们可以命名捕获组,以便稍后使用(?your group here)语法轻松获取它们。我将搜索它是如何在Java中完成的,并在这里发布
编辑:要查看Java如何支持命名组,请参阅答案
您可以测试正则表达式的一个好站点是regex101.com。您可以匹配第一行,然后使用来匹配以下行: Regex
(?:^.*\s([^:,\s]+):\s+([^:\n]+)|\G(?!\A))\s*at\s+(\S+)\((\w+\.\w+):(\d+)\)$
其中:
- 第一场比赛
异常描述^.*\s([^:,\s]+):\s+([^:\n]+)
- 或
上次匹配的结束\G(?!\A)
- 然后
literal\s*at\s+
被空格包围(包括换行符)at
组3中的错误级别(\S+)
组4中的源\((\w+\.\w+)
组5中的行:(\d+)\$
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));
}
}
}
为什么不使用error对象来获取所需的数据呢?好吧,您没有将缺少的部分放入一个组中(在括号中),因此它们不会被报告。您可以创建
(?组)
,并在代码中将它们作为matcher.group(groupName)
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