PowerShell -match运算符和多个组

时间:2009-11-09 19:07:04

标签: .net regex powershell

我在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)

5 个答案:

答案 0 :(得分:9)

我能够通过定义正则表达式然后在该正则表达式上调用.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)

答案 1 :(得分:9)

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

$formattedMessage | Select-String 'regexpattern' -AllMatches

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

答案 2 :(得分: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

答案 3 :(得分:4)

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

并且,通过各种方式,简化你的表达:

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

答案 4 :(得分:0)

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

相关问题