【问题标题】:RegEx to capture execution time with specific text afterwardsRegEx 之后使用特定文本捕获执行时间
【发布时间】:2013-03-04 17:40:49
【问题描述】:

我有以下我正在尝试解析的日志文件。我正在使用正则表达式来收集我需要的信息并完成了大部分工作。我有日志文件的某个部分根据它执行的步骤重复了几次。我可以使用以下正则表达式,然后返回捕获数组,但步骤的顺序可能会改变。我希望能够有把握地捕捉特定步骤。

正则表达式:

\[Total execution Time: (.+) min

日志摘录:

02/19 00:48:46:762 [INFO] [MigrationWizard] [总执行时间:11.05 分钟] [管理员] [(null)] [14]
02/19 00:48:46:762 [INFO] [MigrationWizard] [错误总数:0] [管理员] [(null)] [14]
02/19 00:48:46:762 [INFO] [MigrationWizard] [步骤 1 完成。] [管理员] [(null)] [14]

我是否需要使用前瞻断言来确保总执行时间后跟特定的步骤名称?我如何解释介于两者之间的所有角色?我如何解释多行馈送?我正在使用 C#。

【问题讨论】:

  • 日志摘录中的三行在日志的其余部分是否总是相似的?也就是说,step的执行时间是不是总是后面两行后面跟着step的名字?

标签: c# .net regex regex-lookarounds


【解决方案1】:

试试这个正则表达式

Total execution Time: ([\d.]+).*\r?\n.*\r?\n.*\[Step 1\s

其中“第 1 步”当然需要更改为您希望匹配的步骤。这只会匹配“Step 1”的总执行时间。

确保未启用单行模式(因此 . 与换行符不匹配)

我假设日志条目的顺序总是相同的。

【讨论】:

  • 做到了。查看正则表达式,您似乎在总执行时间后匹配了一定数量的回车。我没有想到。这可能是我尝试的任何方法都失败的原因。谢谢!
  • 不需要多行模式,因为您没有使用 ^$ - 也许您的意思是:确保启用单行模式 not(所以 @ 987654324@ 与换行符不匹配)。另请注意,这将匹配 Step 10Step 11 等,除非您的正则表达式包含尾随空格。
【解决方案2】:

试试这样的:

string strRegex = @"(Total execution Time: )(\d{2}[\.:]\d{2})\s+";
RegexOptions myRegexOptions = RegexOptions.Multiline | RegexOptions.Singleline;
Regex myRegex = new Regex(strRegex, myRegexOptions);

string strTargetString = @"..............";

foreach (Match myMatch in myRegex.Matches(strTargetString))
{
  if (myMatch.Success)
  {
    // ........ do something
  }
}

输入字符串:

02/19 00:48:46:762 [INFO ] [MigrationWizard] [Total execution Time: 11.05 minute(s)] [administrator] [(null)] [14]
02/19 00:48:46:762 [INFO ] [MigrationWizard] [Total number of error(s): 0] [administrator] [(null)] [14]
02/19 00:48:46:762 [INFO ] [MigrationWizard] [Step 1 Done.] [administrator] [(null)] [14]
02/19 00:48:46:762 [INFO ] [MigrationWizard] [Total execution Time: 13:25 minute(s)] [administrator] [(null)] [14]

匹配:

Total execution Time: 11.05
Total execution Time: 13:25

【讨论】:

  • 我不想遍历捕获组,因为可以省略步骤。在这些情况下,输出将列出不正确步骤的步骤值。我将输出格式化为“第 1 步:11.05 分钟”
【解决方案3】:

你的正则表达式

 \[Total execution Time: (.+) min

效率低下,因为.+ 在回溯之前会尽可能多地贪婪地匹配任何字符(换行符除外)以尝试匹配其后的" min"。更好的是.+?,它会在" min"之前匹配尽可能少的字符,更好的是只匹配数字和点[\d.]+或匹配特定格式\d\d\.\d\d

无论如何,要获得[Step 1 是其后的下一步的执行时间,您可以使用,例如

Match m = Regex.Match(str,
    @"\[Total execution Time: ([\d.]+)(?:(?!\[Step ).)+\[Step 1 Done",
        RegexOptions.Singleline
);

if (m.Success) {
    Console.WriteLine(m.Groups[1].Value);         
}

负前瞻(?!\[Step ) 意味着. 将只匹配直到"[Step " 出现在字符串中的字符。如果整个匹配要成功,则必须匹配"[Step 1 Done"

使用RegexOptions.Singleline,因此. 匹配换行符。

或者,您可以将[\d.]+ 之前的模式放在积极的后视中,并将其后的模式放在积极的前瞻中,避免使用捕获组来获取值,但这会使几乎没有什么区别。

【讨论】:

  • 比需要的复杂一点
猜你喜欢
  • 2019-02-10
  • 2013-04-25
  • 2021-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-12
相关资源
最近更新 更多