我有一个日志文件,如下所示:
2012-05-04 01:10:35; 301383027; 00133608663205759673480010256592; 103;错误;摘要处理:119; blah1
blah2
blah3
2012-05-02 01:00:22; 301382163; 00133591322220336011720010256592; 103;错误;摘要处理:119; blah4
blah5
blah6
2012-05-02 01:00:23; 301382163; 00133591322220336011720010256592; 103;错误;摘要处理:119; blah7
blah8
blah9
我希望在每个匹配3个匹配的组中有3个匹配:日期,严重性和消息.
我试过用这种模式
(20[0-9]{2}-[0-2][0-9]-[0-9]{2} [0-2][0-9]:[0-5][0-9]:[0-5][0-9]);[^;]*;[^;]*;[^;]*;([^;]*);(.*)
Run Code Online (Sandbox Code Playgroud)
启用单行选项后,我有一个匹配(整个输入),如果禁用此选项,则不会完全捕获消息(仅与日期在同一行上的部分).
我怎么能拥有与我想要正确捕获的3个值的日志条目一样多的匹配?
编辑:我试图捕获这样的匹配:
日期: 2012-05-04 01:10:35
严重性:错误
消息: AbstractTreatment:119; blah1
blah2
blah3
这里有两个技巧.
"" 不包含"\n",您不需要设置RegexOptions.Multiline.
您需要使用另一个日期/时间模式或结束字符($)作为分隔符,该分隔符不应包含在匹配项中.(否则需要在搜索下一个匹配项之前从输入中排除分隔符).
这需要使用一个称为" 零宽度正向前瞻断言 " 的特殊分组表达式,其语法为(?= subexpression).
为了测试您的日志,我将其保存在"Log"设置变量中.
string log = Settings.Default.Log;
string datePattern = @"20[0-9]{2}-[0-2][0-9]-[0-9]{2} [0-2][0-9]:[0-5][0-9]:[0-5][0-9]";
string pattern = @"(?<date>" + datePattern + @");[^;]*;[^;]*;[^;]*;(?<severity>[^;]*);(?<message>(.|\n)*?)(?=(" + datePattern + @"|$))";
Match mtc = Regex.Match(log, pattern);
while (mtc.Success)
{
Console.WriteLine("Date: " + mtc.Groups["date"].Value);
Console.WriteLine("Severity: " + mtc.Groups["severity"].Value);
Console.WriteLine("Message: " + mtc.Groups["message"].Value);
mtc = mtc.NextMatch();
}
Run Code Online (Sandbox Code Playgroud)
然后输出如下,
Date: 2012-05-04 01:10:35
Severity: ERROR
Message: AbstractTreatment:119;blah1
blah2
blah3
Date: 2012-05-02 01:00:22
Severity: ERROR
Message: AbstractTreatment:119;blah4
blah5
blah6
Date: 2012-05-02 01:00:23
Severity: ERROR
Message: AbstractTreatment:119;blah7
blah8
blah9
Run Code Online (Sandbox Code Playgroud)