c# - 应该使用什么正则表达式来匹配多行日志消息?

标签 c# regex powershell batch-file

我正在编写一个批处理文件来处理我的应用程序的日志文件。

日志文件可能包含开头与正则表达式 ^.{24}\[ERROR 匹配的消息,后跟一些我需要查找的连续行。日志消息的结尾将由正则表达式 ^.{24}\[[A-Z

的下一个匹配项表示

目前我正在使用正则表达式 (?m)^.{24}\[ERROR(.*\r?\n?.)*?^.{24}\[[A-Z] 找到这样的消息。但是性能非常差,因为它目前已经为几 MB 的日志文件运行了几分钟。

我正在使用的完整批处理文件是:

@Echo off

powershell -Command "& {[System.Text.RegularExpressions.RegEx]::Matches([System.IO.File]::ReadAllText('application.log'), '(?m)^.{24}\[ERROR(.*\r?\n?.)*?^.{24}\[[A-Z]') | Set-Content result.txt}"

如上所述,我应该使用什么正则表达式来匹配日志消息?

最佳答案

重点是您的正则表达式包含 (.*\r?\n?.)*? 部分,其中包含嵌套的可选(即匹配空文本)子模式。一旦在一个组中被量化,他们就会让正则表达式引擎在承认没有匹配之前尝试很多组合,从而导致灾难性的回溯或超时问题。

其中一个解决方案是使用惰性点匹配模式和 DOTALL 修饰符:

(?ms)^.{24}\[ERROR(.*?)^.{24}\[[A-Z]

参见 regex demo

.NET 正则表达式引擎比 PCRE、Python re、JavaScript 更好地处理子模式。

然而,惰性匹配会降低性能,最好将其展开。我建议

(?m)^.{24}\[ERROR(.*(?:\n(?!.{24}\[[A-Z]).*)*)\n.{24}\[[A-Z]

参见 another regex demo

请注意,这 2 个在它们匹配的内容上是等价的,但在它们匹配的方式上不同。虽然第一个尝试匹配模式的尾部并在失败时将 1 个字符扩展一个,但展开的模式只是抓取文本部分直到换行符,所有没有 24 个非换行符的换行符后跟 [ 和一个大写 ASCII 字母,这样更快

RegexHero.net 测试:

enter image description here

关于c# - 应该使用什么正则表达式来匹配多行日志消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38873769/

相关文章:

c# - 是否会为 C# 中的类的每个实例创建一个属性实例?

c# - ASP.NET MVC Html.EnumDropDownListFor 选定值

c# - 在Sharepoint 2010中的Web部件的编辑菜单中添加按钮

regex - 如何匹配由分隔符分隔的重复单词

powershell - 如何检查网络端口访问并显示有用的消息?

powershell - 如何使用 powershell 脚本安装证书

c# - 在数据库中克隆相当大的子树的高效方法?

python - 正则表达式 split 方法中的分隔符无法正常工作

.net - 从 [regex] 类型加速器表达式中捕获命名组的 PowerShell 语法是什么?

regex - Flex 正则表达式文字 char