regex onigurama负面的背后不起作用

时间:2016-11-28 10:59:43

标签: regex logstash regex-lookarounds logstash-grok oniguruma

我正在尝试使用onigurama regex库(在Logstash中)使用负面后视来捕获日志文件中的一行,但它似乎仍然匹配它不应该的行。我试图仅匹配顶级异常,而不是以引起的:

开头的异常

有人帮我写了这个

在Rubular上测试过 http://rubular.com/r/N3AzySNHiS

经过测试的正则表达式

^(?<!Caused by: ).*?Exception

(?<!^Caused by: ).*?Exception

消息:

2016-11-15 05:19:28,801 ERROR [App-Initialisation-Thread] appengine.java:520 Failed to initialize external authenticator myapp Support Access || appuser@vm23-13:/mnt/data/install/assembly app-1.4.12@cad85b224cce11eb5defa126030f21fa867b0dad
java.lang.IllegalArgumentException: Could not check if provided root is a directory
    at com.myapp.jsp.KewServeInitContextListener$1.run(QServerInitContextListener.java:104)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.nio.file.NoSuchFileException: fh-ldap-config/
    at com.upplication.s3fs.util.S3Utils.getS3ObjectSummary(S3Utils.java:55)
    at com.upplication.s3fs.util.S3Utils.getS3FileAttributes(S3Utils.java:64)

Logstash结果

"exception" => "Caused by: java.nio.file.NoSuchFileException"

2 个答案:

答案 0 :(得分:1)

似乎在Logstach环境中设置了一些其他选项。从我的测试中,我怀疑启用了“详细”或“忽略空格”选项。另外,要排除 public string ImageToBase64(Image image, System.Drawing.Imaging.ImageFormat format) { using (MemoryStream ms = new MemoryStream()) { // Convert Image to byte[] image.Save(ms, format); byte[] imageBytes = ms.ToArray(); // Convert byte[] to Base64 String string base64String = Convert.ToBase64String(imageBytes); return base64String; } } 的任何其他问题(可能会重新定义以匹配换行符号),您可以使用明确的.(任何字符不是[^\r\n]\r ):

\n

转义空间将始终与单个常规空间匹配。

答案 1 :(得分:0)

注意:我在整个答案中假设问题中显示并在下面重复的2条单独的日志行不包含换行符,并且已通过logstash中的多行编解码器插件处理或以某种方式删除。

TL; DR使用负面背后的解决方案

如果后来给予适当的锚点,那么背后的负面看法将起作用。看看这两行就可以了:

^(?<!Caused by: )java.*Exception

注意:它可能只是^(?<!Caused by: )j.*Exception,但我认为java使其更具可读性。

示例代码问题解释

给定正则表达式的问题:^(?<!Caused by: ).*?Exception(?<!^Caused by: ).*?Exception是不情愿的*?量词,它允许某些内容匹配0次或更多次。现在正如本answer中所解释的那样,正则表达式引擎从字符串的开头开始,然后向左移动进行写入。尽可能少的字符数(因为它不情愿)只是引擎无法匹配Exception然后它会逐渐尝试匹配.之前的任何内容(Exception)(“回溯”)向左移动写。

因此,正则表达式引擎一直尝试匹配另一个字符(从左到右),直到消耗完后找到Exception。因此字符串

Caused by: java.nio.file.NoSuchFileException: fh-ldap-config/ at com.upplication.s3fs.util.S3Utils.getS3ObjectSummary(S3Utils.java:55) at com.upplication.s3fs.util.S3Utils.getS3FileAttributes(S3Utils.java:64)

匹配是因为引擎已消耗了Exception之前的所有内容,而Caused by:在此匹配之前未出现。基本上.*?消耗了负面的后视所需要的Caused by:

深入了解

要了解正则表达式引擎实际使用的外观,我建议您查看此answer

我认为很容易被量词和外观所吸引,作为一般规则,我认为外观需要通过具体的东西(不是.锚定。为了理解我的意思,让我们看看给定正则表达式与贪婪的*量词的微小变化。正则表达式^(?<!Caused by: ).*Exception也匹配引用的字符串。

原因是贪婪的*限定符开始于消耗整个字符串,然后从右向左回溯,如上面第一个链接的答案中所述。出于同样的原因(但从另一方面),一旦引擎匹配Exception,它就会保留从字符串开头到Exception的所有内容。然后它查看它消耗的内容并且找不到Caused by:并成功匹配字符串。

摘要中,作为一般规则

使用贪婪或不情愿的量词时,始终固定外观。