2015-11-06 55 views
0

我設計了正則表達式來匹配異常消息字段。正則表達式提取異常消息字段

^.*\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 

任何人有匹配異常消息的領域更好的正則表達式?

+4

你爲什麼不只是使用錯誤對象來獲取數據,你需要? –

+0

那麼,你沒有把缺少的部分放在一個組中(括號內),所以他們不會被報告。 – RealSkeptic

回答

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

1

任何時候你使用()你創建一個捕獲組。因此,在您的正則表達式中,您可以從4個捕獲組中提取數據。

第一個捕獲異常名稱,我相信它是正確的,但我不知道所有的可能性。

第二個捕獲消息。我相信它應該是可選的,所有例外都有消息?包括自定義的?除此之外,這似乎是正確的。我只會添加一個$後,以確保它到達行尾。

問題始於應該捕獲方法名稱的第三個捕獲組,我相信。更改此零件:\S+\((\w+)\.\w+:(\d+)\)$([\w.]+\w+)\(([\w.]+\w+)\:(\d+)\)$

添加的3個捕獲組用於方法名稱,文件名和行號。

此外,添加一個額外的+,讓您捕捉到多個錯誤行

最後的正則表達式是:^.*\s([^:,\s]+):\s+([^:]+)$(?:\s*at\s+([\w\.]+\w+)\(([\w\.]+\w+)\:(\d+)\))+

然而,由多羅指出,你不能捕獲多與部分比賽相同的正則表達式,這就是你想要做的錯誤行。

你應該打入2點的正則表達式:^.*\s([^:,\s]+):\s+([^:]+)$\s*at\s+([\w\.]+\w+)\(([\w\.]+\w+)\:(\d+)\)+

而且所有這一切,我不知道有關Java正則表達式,但在C#中,我們可以命名捕獲組,這樣就可以輕鬆搞定之後他們使用(你的團隊在這裏)的語法。我將搜索它是如何在Java中完成的,並在這裏發佈。

編輯:要了解Java如何支持命名組,請參閱this的答案。

一個很好的網站,你可以測試你的regexes是regex101.com。

+0

您可以創建'(?組)'並在代碼中將它們引用爲'matcher.group(groupName)' – Mariano