我正在尝试使用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"
答案 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:
并成功匹配字符串。
摘要中,作为一般规则
使用贪婪或不情愿的量词时,始终固定外观。