.net PowerShell -match 运算符和多个组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1703061/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 13:33:16  来源:igfitidea点击:

PowerShell -match operator and multiple groups

.netregexpowershell

提问by Eric Schoonover

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 -matchoperator 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 Regexobject. Can someone explain what I am doing wrong?

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

Relevant PowerShell Script

相关的 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

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)

采纳答案by Keith Hill

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

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

$formattedMessage | Select-String 'regexpattern' -AllMatches

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

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

回答by Eric Schoonover

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

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

回答by Jeff Hillman

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.

-match 操作符只能使用一次;它不会对输入进行全局匹配。基思·希尔 (Keith Hill) 在此处为 Microsoft Connect 上的 -matchall 运营商提出了建议。

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 语句来完成同样的事情:

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

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

如果$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

回答by genio

http://www.johndcook.com/regex.htmlgives a decent example

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

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("
  • 从行首开始
  • 捕获导致第一个的所有字符 -
  • 确保有一个 -
  • 跳过空格
  • 确保单词“duration(”存在
  • 捕获“持续时间(”之后的所有数字

回答by Nathan Hartley

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

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