提取最后一次由'引起的堆栈跟踪与正则表达式

时间:2016-03-28 18:32:33

标签: regex logstash logstash-grok

不幸的是,我还不是一名正则表达式专家,因此遇到以下问题: 假设我有一个包含多个链式异常的Java堆栈跟踪,我想要达到的是从&#34开始提取最后一行;由"引起。

javax.servlet.ServletException: Something bad happened
     at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:60)
.
.
Caused by: com.example.myproject.MyProjectServletException
.
.
Caused by: This is the line I want to capture

到目前为止,我发现Caused by.(?!.*Caused by)基于负向前瞻,给了我最后一个"由"引起删除所有标签和空格后,(但不是其余部分)。有没有办法让我得到我想要的结果?如果必须删除所有空格,那对我来说没问题。谢谢!

编辑:对不起,我想我忘记了非常重要的事情。使用' substring'将是一个完美的Java解决方案,但我需要的是一个正则表达式,我可以用于Logstash中的grok模式。

5 个答案:

答案 0 :(得分:5)

以下是基于贪心量词的非基于外观的解决方案:

\A[\s\S]*\nCaused by:\s*(?<LastCausedBy>.*)\Z

请参阅the regex demo

模式匹配

  • \A - 字符串的开头
  • [\s\S]* - 尽可能多的任意0个字符(实际上,抓住所有文本到最后然后向后移动 - 回溯 - 找到最后一个......)
  • \nCaused by: - 换行后跟Caused by:
  • \s* - 0+空白符号
  • (?<LastCausedBy>.*) - 除换行符之外的任何0 +字符(捕获到LastCausedBy命名组
  • \Z - 字符串结尾

Grok Debugger测试:

enter image description here

答案 1 :(得分:1)

我建议您将substringlastIndexOf结合使用以获得Caused by的最后一次出现

就像那样:

String lastCaused = yourStacktraceAsString.substring(yourStacktraceAsString.lastIndexOf("Caused by"));

答案 2 :(得分:1)

这可以通过正则表达式来完成,但在这种情况下,它可能更简单,只需要子串。假设您的异常堆栈跟踪是在String调用ex:

中捕获的
ex.substring(ex.lastIndexOf('Caused by:'))

答案 3 :(得分:1)

谢谢@Pshemo,你的想法让我走向了解决方案。经过数小时的反复试验,以下模式按预期工作:

(?m)(Caused by:)(?![\s\S.]*Caused by).*$

这与评论中的建议非常接近!

答案 4 :(得分:0)

正则表达式是棘手的,易碎的,难以阅读和维护。消极的前瞻使情况变得更糟。仅在需要时使用它们。我建议只需迭代text.split("\n"),查找以Caused by:开头的行,并将其保留在循环的末尾。