正则表达式用于提取异常消息字段

时间:2015-11-06 11:16:38

标签: 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 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

任何人都有更好的正则表达式来匹配异常消息的字段吗?

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+)\)$

其中:

  • 第一次non-capturing group次匹配
    • ^.*\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

ideone demo

答案 2 :(得分:0)

您无法使用正则表达式进行动态匹配。你的目标必须分两步完成。

第1步 - 提取错误标题:

ERROR ([^:]+): (.*)

https://regex101.com/r/eQ3rI5/1

第2步 - 提取错误信息

(?:\s+at ([^(]+)\(([^:]+):(\d+))\)

https://regex101.com/r/eQ3rI5/2