【问题标题】:PowerShell -match operator and multiple groupsPowerShell -match 运算符和多个组
【发布时间】:2021-06-18 23:47:06
【问题描述】:

我在 PowerShell 中处理以下日志条目我正在尝试使用 -match 运算符提取所有活动名称和持续时间,但我只得到一个匹配组。当我使用 Regex 对象在 C# 中做同样的事情时,我没有得到所有的匹配。有人可以解释我做错了什么吗?

相关的 PowerShell 脚本

$formattedMessage -match "(Get\sClient\sModel|Parse\sExpression|Get\sAbstract\sQuery|Compile\sQuery|Execute\sQuery|Get\sQuery\sPlan\sComplexity|Async\sTotal|Total)\s-\sduration\(([0-9]*)" | out-null
$matches

输出

Name  Value
----  -----
0     Get Client Model - duration(0
1     Get Client Model
2     0

日志条目示例:

Timestamp: 11/9/2009 6:48:41 PM
Message:
Category: QueryService
Priority: 3
EventId: 1001
Severity: Information
Title: SPARQL Query Response
Machine: SPOON16-SERVER
App Domain: KnowledgeBaseHost.exe
ProcessId: 2040
Process Name: D:\QueryService\QSHost.exe
Thread Name:
Win32 ThreadId:8092
Extended Properties:
Key - Workflow_cbbdd58b-e574-4054-88d4-1dd7a56dc9d9
Timeout - 1800
Result Format - WireTable
Result from Registry - False
Compiled Query from Cache - True
Result Count - 28332
Query Plan Complexity - 661622
Get Client Model - duration(0) start(0)
Parse Expression - duration(0) start(0)
Get Abstract Query - duration(0) start(0)
Compile Query - duration(0) start(0)
Get Query Plan - duration(0) start(1)
Execute Query - duration(63695) start(1)
Get Query Plan Complexity - duration(0) start(63696)
Get Executed Operations - duration(0) start(63696)
Total - duration(63696) start(0)
Async Total - duration(63696) start(0)

【问题讨论】:

    标签: .net regex powershell


    【解决方案1】:

    您可以使用 V2 中的 Select-String cmdlet 执行此操作,但您需要指定 -AllMatches 开关,例如:

    $formattedMessage | Select-String 'regexpattern' -AllMatches
    

    请记住,使用 -match 运算符,您要做的主要事情是寻找“a”匹配,即,正则表达式模式是否匹配?

    【讨论】:

      【解决方案2】:

      我能够通过定义Regex 然后在该正则表达式上调用 .Matches 来获取所有组。我仍然很想知道这是否可以使用 PowerShell 中的 -match 运算符来完成。

      $detailRegex = [regex]"(Get\sClient\sModel|Parse\sExpression|Get\sAbstract\sQuery|Compile\sQuery|Execute\sQuery|Get\sQuery\sPlan\sComplexity|Async\sTotal|Total)\s-\sduration\(([0-9]*)"
      $detailRegex.Matches($formattedMessage)
      

      【讨论】:

      • 最佳答案,允许您非常轻松地将结果分配给变量,以便您可以将其作为匹配数组处理。
      【解决方案3】:

      http://www.johndcook.com/regex.html 给出了一个不错的例子

      而且,一定要简化你的表达方式:

      ^([^-]+)\s*-\s*duration\(([0-9]+)
      
      • 从行首开始
      • 捕获前一个字符之前的所有字符 -
      • 确保有一个 -
      • 跳过空格
      • 确保单词“duration(”存在
      • 捕获“duration(”之后的所有数字

      【讨论】:

      • 我尝试按照您的描述简化正则表达式(在创建我那里的讨厌的表达式之前)并且 powershell 不会生成任何匹配项。
      • 我获取了您的样本数据,并使用上面的确切表达式得到了正确的结果。
      • powershell 将使用提供的正则表达式生成匹配项
      【解决方案4】:

      -match 运算符只能使用一次;它不对输入进行全局匹配。 Keith Hill 建议在 Microsoft Connect here 上使用 -matchall 运算符。

      我会建议另一种方法。如果日志条目在文件中,您可以使用 switch 语句来完成同样的事情:

      switch -regex -file .\log.txt { $entryRegex { $matches[1] + ", " + $matches[2] } }
      

      如果$entryRegex 具有您定义的正则表达式,这是我使用此语句得到的输出:

      Get Client Model, 0
      Parse Expression, 0
      Get Abstract Query, 0
      Compile Query, 0
      Execute Query, 63695
      Get Query Plan Complexity, 0
      Total, 63696
      Async Total, 63696
      

      【讨论】:

        【解决方案5】:

        您可以在表达式中包含Regular Expression Options,但遗憾的是,全局似乎不是可用选项之一。

        【讨论】:

          猜你喜欢
          • 2018-07-30
          • 1970-01-01
          • 1970-01-01
          • 2019-05-06
          • 2013-01-24
          相关资源
          最近更新 更多