PowerShell - оператор совпадения и несколько групп - PullRequest
11 голосов
/ 09 ноября 2009

У меня есть следующая запись в журнале, которую я обрабатываю в PowerShell. Я пытаюсь извлечь все имена и длительности действий с помощью оператора -match, но я получаю только одну группу совпадений. Я не получаю все совпадения, которые я вижу, когда я делаю то же самое в C #, используя объект Regex. Может кто-нибудь объяснить, что я делаю не так?

Соответствующий скрипт 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 ]

9 голосов
/ 09 ноября 2009

Вы можете сделать это с помощью командлета Select-String в V2, но вам необходимо указать ключ -AllMatches, например ::100100

$formattedMessage | Select-String 'regexpattern' -AllMatches

Имейте в виду, что с оператором -match основное, что вы делаете, - это поиск совпадения "a", т. Е. Сопоставление с шаблоном регулярного выражения.

9 голосов
/ 09 ноября 2009

Мне удалось получить все группы, определив регулярное выражение, а затем вызвав .Matches для этого регулярного выражения. Еще интересно узнать, можно ли это сделать с помощью оператора -match в 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)
4 голосов
/ 09 ноября 2009

http://www.johndcook.com/regex.html дает достойный пример

И, конечно же, упростите ваше выражение:

^([^-]+)\s*-\s*duration\(([0-9]+)
  • начало в начале строки
  • захватить всех персонажей, ведущих к первому -
  • убедитесь, что есть -
  • пропустить пробел
  • убедитесь, что слово "duration (" существует)
  • захватить все цифры после "duration ("
4 голосов
/ 09 ноября 2009

Оператор -match предназначен для использования только один раз; это не делает глобальное соответствие на входе. Кит Хилл выдвинул предложение по использованию оператора -matchall в Microsoft connect здесь .

Я предложу другой способ сделать это. Если запись журнала находится в файле, вы можете использовать оператор 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
0 голосов
/ 21 марта 2012

Вы можете включить Параметры регулярного выражения в выражение, но, к сожалению, Global не является одним из доступных вариантов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...