正则表达式拆分模式多行

Posted

技术标签:

【中文标题】正则表达式拆分模式多行【英文标题】:Regex split pattern multiple lines 【发布时间】:2019-04-14 15:52:56 【问题描述】:

我需要从 txt 文件中读取一些日志数据并进行相应的拆分。 我的示例文件看起来像这样:

11:03:04.234 DEBUG event occurred  
11:03:05.345 INFO another event occurred  
11:03:06.222 ERROR notice that this event
             occupies multiple lines
             as errors can be from multiple sources
             and I have no control over this
11:04:07.222 INFO fourth event has happened

我决定不使用StreamReader,因为它看起来是最有效的方式。我使用StreamReaderReadToEnd() 方法读取了文件的所有内容并接收到一个大字符串。然后,我尝试使用正则表达式来拆分字符串。到目前为止,我能够提出的正则表达式模式如下所示:([0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9].*). 当然,在 Regex 解析多行事件之前,它工作得非常好。 我使用this tool 来测试我的模式。

【问题讨论】:

试试(?m)^(?!\A)(?=\d2:\d2:\d2\.\d3) 那么问题是什么? 如何读取一行,检查时间戳,如果有,解析 INFO/DEBUG/ERROR 部分,捕获文本,创建一个新的 LogResd 条目。如果行首没有时间戳,则丢弃前导空格并将文本连接到最后创建的条目 【参考方案1】:

你可以使用

Regex.Split(s, @"(?m)^(?!\A)(?=\d2:\d2:\d2\.\d3)")

见regex demo

详情

(?m)^ - 行首 (?!\A) - 但不是字符串的开头 (?=\d2:\d2:\d2\.\d3) - 后跟 2 位、:、2 位、:、2 位、. 和 3 位。

结果:

【讨论】:

【参考方案2】:

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

(?=\d2:\d2:\d2\.\d3)(?:[\s\S](?!\d2:\d2:\d2\.\d3))+

从前瞻开始:2 位数字、一个冒号、2 位数字、一个冒号、2 位数字、一个点和 3 位数字。

然后它启动一个非捕获组,它匹配任何字符(包括换行符),对与上面相同的模式使用负向预测。该组重复一次或多次。

基本上它匹配以时间开始并一直持续到到达新时间值(或结束)的行。

MatchCollection 将包含所有匹配项。

使用方法:

string text = "11:03:04.234 DEBUG event occurred\r\n11:03:05.345 INFO another event occurred\r\n11:03:06.222 ERROR notice that this event\r\noccupies multiple lines\r\nas errors can be from multiple sources\r\nand I have no control over this\r\n11:04:07.222 INFO fourth event has happened";
Regex regex = new Regex(@"(?=\d2:\d2:\d2\.\d3)(?:[\s\S](?!\d2:\d2:\d2\.\d3))*");
foreach (Match match in regex.Matches(text))

    Console.WriteLine(match.Value);

【讨论】:

以上是关于正则表达式拆分模式多行的主要内容,如果未能解决你的问题,请参考以下文章

Python: 正则表达式匹配多行,实现多行匹配模式

C# 正则表达式拆分为 Java 模式拆分

Python正则表达式,多行匹配模式..为啥这不起作用?

正则表达式 python 多行

预先将正则表达式模式附加到拆分并将案例类映射到拆分

如何使用正则表达式多行模式