13

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)

5 Answers 5

11

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?

Sign up to request clarification or add additional context in comments.

Comments

11

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)

1 Comment

best answer, allows you to assign your result to a variable very easily so you can just handle it as an array of matches.
4

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("

3 Comments

I tried simplifying the regex as you described (previous to creating the nasty one I have there) and powershell doesn't generate any matches.
I took your sample data and was getting proper results with the exact expression above.
powershell will generate matches using the provided regex
4

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.