繁体   English   中英

使用正则表达式解析多行日志条目

[英]Parse multiline log entries using a regex

我正在尝试使用此正则表达式解析C#应用程序中的日志条目: (^[0-9]{4}(-[0-9]{2}){2}([^|]+\\|){3})(?!\\1)用于日志格式,如[日期(某种格式)] | [等级] | [appname] | [留言]

在哪里(我认为):

  • ^匹配一行的开头(在regex101上启用/ gm
  • [0-9]{4}(-[0-9]{2}){2}之后是2015-03-03的开始日期
  • ([^|]+\\|){3})后跟剩余的日期,日志级别和应用程序名称
  • (?!\\1)后面没有新的日志条目的开头(应该是消息)

例如,我有以下4个日志条目(由换行符分隔以便澄清):

2015-03-03 19:30:47.2725|INFO|MyApp|This is a single line log message.

2015-03-03 19:31:29.1209|INFO|MyApp|This log message has multiple
lines with
2015-03-03
a date in it.

2015-03-03 19:32:50.1106|INFO|MyApp|This log message has
multiple lines
but just text only.

2015-03-03 19:33:20.2683|ERROR|MyApp|This log message has multiple lines but
also some confusing text like
2015-03-03 19:33:20.2683|ERROR| which should
still be a valid log message.

但是当我在regex101上测试它时,正则表达式不捕获消息,可能是因为我不明白如何捕获负向前瞻。

如果我在正则表达式中包含.*(^[0-9]{4}(-[0-9]{2}){2}([^|]+\\|){3}).*(?!\\1)它匹配消息但只有一行(因为.与换行符不匹配)。

那么如何捕获(多行)消息呢?

你可以使用这个正则表达式:

(^\d{4}(-\d{2}){2}([^|]+\|){3})([\s\S]*?)\n*(?=^\d{4}.*?(?:[^|\n]+\|){3}|\z)

RegEx演示

这个正则表达式也应该在C#中工作,只需确保使用MULTILINE标志。

这样的事情应该有效。
请参阅正则表达式中的注释。
mod :为EOS或单行消息选择换行符)

 @"(?m)^[0-9]{4}(?:-[0-9]{2}){2}(?:[^|\r\n]+\|){3}((?:(?!^[0-9]{4}(?:-[0-9]{2}){2}(?:[^|\r\n]+\|){3}).*(?:\r?\n)?)+)"

格式化( 使用此 ):

 (?m)                          # Modifier - multiline
 ^                             # BOL
 [0-9]{4}                      # Message header
 (?: - [0-9]{2} ){2}
 (?: [^|\r\n]+ \| ){3}
 (                             # (1 start), The Message
      (?:
           (?!                           # Assert, not a Message header
                ^                             # BOL
                [0-9]{4} 
                (?: - [0-9]{2} ){2}
                (?: [^|\r\n]+ \| ){3}
           )
           .*                            # Line is ok, its part of the message
           (?: \r? \n )?                 # Optional line break
      )+
 )                             # (1 end)

输出:

 **  Grp 0 -  ( pos 0 , len 74 ) 
2015-03-03 19:30:47.2725|INFO|MyApp|This is a single line log message.


 **  Grp 1 -  ( pos 36 , len 38 ) 
This is a single line log message.

--------------

 **  Grp 0 -  ( pos 74 , len 108 ) 
2015-03-03 19:31:29.1209|INFO|MyApp|This log message has multiple
lines with
2015-03-03
a date in it.


 **  Grp 1 -  ( pos 110 , len 72 ) 
This log message has multiple
lines with
2015-03-03
a date in it.

--------------

 **  Grp 0 -  ( pos 182 , len 97 ) 
2015-03-03 19:32:50.1106|INFO|MyApp|This log message has
multiple lines
but just text only.


 **  Grp 1 -  ( pos 218 , len 61 ) 
This log message has
multiple lines
but just text only.

--------------

 **  Grp 0 -  ( pos 279 , len 186 ) 
2015-03-03 19:33:20.2683|ERROR|MyApp|This log message has multiple lines but
also some confusing text like
2015-03-03 19:33:20.2683|ERROR| which should
still be a valid log message.

 **  Grp 1 -  ( pos 316 , len 149 ) 
This log message has multiple lines but
also some confusing text like
2015-03-03 19:33:20.2683|ERROR| which should
still be a valid log message.

你使用什么正则表达式引擎? 例如,在Java中有一个标志来告诉“。” 匹配换行符。

以下正则表达式似乎可以解决问题:

/(([0-9]{4})(-[0-9]{2}){2}([^|]+\|){3})((.(?!\2))*)/sg

我对您的查询所做的修改主要是一些清理(您的日期捕获组错误)。 然后我加了一个。 和*在最后的捕获组中。 https://regex101.com/r/fU1vV1/2

最重要的部分是使用sg标志。 g让它获得所有比赛。 s使它像一条线一样对待它(否则你的负面前瞻永远不会起作用)。 如果您可以保证评论在一行(它们在您的示例中),那么所有这些都是不必要的,因为您可以捕获到行的末尾。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM