English 中文(简体)
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 "(GetsClientsModel|ParsesExpression|GetsAbstractsQuery|CompilesQuery|ExecutesQuery|GetsQuerysPlansComplexity|AsyncsTotal|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:QueryServiceQSHost.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]"(GetsClientsModel|ParsesExpression|GetsAbstractsQuery|CompilesQuery|ExecutesQuery|GetsQuerysPlansComplexity|AsyncsTotal|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.





相关问题
Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How do I compare two decimals to 10 decimal places?

I m using decimal type (.net), and I want to see if two numbers are equal. But I only want to be accurate to 10 decimal places. For example take these three numbers. I want them all to be equal. 0....

Exception practices when creating a SynchronizationContext?

I m creating an STA version of the SynchronizationContext for use in Windows Workflow 4.0. I m wondering what to do about exceptions when Post-ing callbacks. The SynchronizationContext can be used ...

Show running instance in single instance application

I am building an application with C#. I managed to turn this into a single instance application by checking if the same process is already running. Process[] pname = Process.GetProcessesByName("...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...

热门标签