我正在解析一些符合模式的文件,以生成人类可读的报告。我使用正则表达式来解析这些文件。
2012-05-10 08:00:00.155: BROADCAST - Body: <?xml version="1.0" encoding="UTF-8" standalone="yes"?><Data></Data>. MessageProperties [headers={X_Day=20120510}]
2012-05-10 08:00:00.155: BROADCAST - Body: <?xml version="1.0" encoding="UTF-8" standalone="yes"?><Data></Data>. MessageProperties [headers={X_Day=20120510}]
2012-05-10 08:00:00.155: REQUEST - Body: <?xml version="1.0" encoding="utf-8"?>
<Data xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<field1>field1.val</field1>
<field2>field2.val</field2>
</Data>. MessageProperties [headers={X_Day=20120510}, correlationId=[51, 56, 100, 54, 48, 48, 97, 54, 51, 99, 102, 100, 52, 102, 97, 51, 98, 51, 57, 52, 52, 49, 49, 50, 54, 97, 56, 100, 49, 48, 53, 98], other=blabla]
我想提取每个记录的时间部分,xml部分和属性部分。
目前我有这个正则表达式,它给了我想要的东西(我没有问题,如果可以帮助提高正则表达式的速度,可以在以后的处理中提取所需的确切位) :
((?:[0-9]{1,4}[-| |:|\.])+[0-9]{1,3}): .*Body: ((?:.|>\n|>\r|>\r\n)*\. MessageProperties )(\[.*\])
文件可能很大(如2000-10000匹配和100Mb),所以我想稍微优化一下。目前的问题是我所有的回溯。*在body之前和(?:。|&gt; \ n |&gt; \ r \ n)*之前的MessageProperties(我需要包含该行)明确地打破我给出的第三个示例记录。
有没有办法优化所有这些回溯?我无法找到方法。
我使用 regex101 进行开发,然后将其调整为 .Net 。
答案 0 :(得分:2)
尽量避免单个字符替换,将部分量化到右侧而不是左侧部分,并尽可能使用字符类。使用unroll the loop principle可以更好地展开两个字符串之间的未知文本(即使您很想使用.*
或.*?
)。
您可以使用
^([0-9]{4}-[- :.0-9]*):\s+[^-]*\s+-\s+Body:\s+([^.]*(?:\.(?!\s+MessageProperties\s)[^.]*)*\.\s+MessageProperties\s+)(\[.*])
请参阅regex demo
<强>详情
^
- 开始一行(与RegexOptions.Multiline
选项一起使用,或者在模式前加(?m)
时)([0-9]{4}-[- :.0-9]*)
- 第1组:
[0-9]{4}
- 4位数-
- 连字符[- :.0-9]*
- 0位数,.
,:
,-
或空格字符
- :\s+[^-]*\s+-\s+
- :
,1 +空格,除-
以外的0 +字符,1 +空格,-
,1 +空格Body:
- 子字符串\s+
- 1+空格([^.]*(?:\.(?!\s+MessageProperties\s)[^.]*)*\.\s+MessageProperties\s+)
- 第2组:
[^.]*(?:\.(?!\s+MessageProperties\s)[^.]*)*
- 已展开的(?s:.*?)
:.
以外的任何0 +字符,后跟.
的0 +序列,未跟随MessageProperties
1 +个空格,然后是.
\.\s+
- .
和1 +空格MessageProperties
- 子字符串\s+
- 1+空格(\[.*])
- 第3组:[
后跟除了换行符之外的任何0 +字符,然后是]
。