我正在尝试使用此正则表达式解析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)
它与消息匹配但只有一行(因为.
与换行符不匹配)。
那么如何捕获(多行)消息?
答案 0 :(得分:3)
您可以使用此正则表达式:
(^\d{4}(-\d{2}){2}([^|]+\|){3})([\s\S]*?)\n*(?=^\d{4}.*?(?:[^|\n]+\|){3}|\z)
这个正则表达式也适用于C#,只需确保使用MULTILINE
标志。
答案 1 :(得分:3)
这样的事情应该有效 请参阅正则表达式中的注释 ( 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)?)+)"
格式化(with this):
(?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.
答案 2 :(得分:-2)
你使用什么正则表达式引擎?例如,在Java中,有一个标志可以告诉"。"匹配换行符。
以下正则表达似乎可以解决问题:
/(([0-9]{4})(-[0-9]{2}){2}([^|]+\|){3})((.(?!\2))*)/sg
我对您的查询所做的修改主要是一些清理(您的日期捕获组错误)。然后我加了一个。和*在最后的捕获组中。 https://regex101.com/r/fU1vV1/2
最重要的部分是使用sg标志。 g让它获得所有比赛。 s使它像一条线一样对待它(否则你的负面前瞻永远不会起作用)。如果您可以保证评论在一行(他们在您的示例中),所有这些都是不必要的,因为您可以捕获到该行的末尾。