开发者

PowerShell -match operator and multiple groups

I have the following log entry that I am processing in PowerShell I'm trying to extract all the activity names and durations using the -match operator but I am only getting one match group back. I'm not getting all of the matches that I see when I do the same thing in C# using the Regex object. Can someone explain what I am doing wrong?

Relevant PowerShell Script

$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

Output

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

Log Entry Example:

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)


You can do this with the Select-String cmdlet in V2, but you need to specify the -AllMatches switch, e.g.:

$formattedMessage | Select-String 'regexpattern' -AllMatches

Keep in mind that with the -match operator the primary thing you are doing is looking for "a" match, i.e., is the regex pattern matched or not?


I was able to get all of the groups by defining a Regex and then calling .Matches on that Regex. I am still curious to know if this can be done with the -match operator in PowerShell.

$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)


http://www.johndcook.com/regex.html gives a decent example

And, by all means, simplify your expression:

^([^-]+)\s*-\s*duration\(([0-9]+)
  • start at the beginning of the line
  • capture all characters leading up to the first -
  • make sure there's a -
  • skip whitespace
  • make sure the word "duration(" exists
  • capture all digits after "duration("


The -match operator is meant to be used just once; it doesn't do a global match on the input. Keith Hill put a suggestion for a -matchall operator on Microsoft Connect here.

I'll suggest another way to do it. If the log entry is in a file, you can use the switch statement to accomplish the same thing:

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

This is the output I get with this statement if $entryRegex has the regular expression you defined:

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


You can include Regular Expression Options in an expression, but sadly, Global does not appear to be one of the available options.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜