Сортировать по именованной группе захвата в регулярном выражении в powershell - PullRequest
1 голос
/ 19 января 2020

У меня есть регулярное выражение, определенное следующим образом:

$regexpo = "^Amma\s(?'version'(\d+\.){3}\d)\.zip$"

Вышеуказанное выражение имеет метку, прикрепленную к группе - (\ d +.) {3} \ d)

И я Я использую его следующим образом:

$Library =  $wholeContent | 
  Where-Object { $_.Name -match $regexpo } | 
    Sort-Object Name -Descending

Но я хочу вместо этого отсортировать его по помеченной группе в пределах определенного регулярного выражения, которое представляет номер версии.

Ответы [ 2 ]

1 голос
/ 19 января 2020

Используйте Sort-Object с вычисляемым свойством (блок сценария ({ ... }), который оценивается для каждого входного объекта, отраженного в $_), следующим образом:

# Sample input
$wholeContent = 
  [pscustomobject] @{ Name = 'Amma 10.0.0.1.zip'; Type = '...' },
  [pscustomobject] @{ Name = 'Not a match' ; Type = '...' },
  [pscustomobject] @{ Name = 'Amma 1.0.0.2.zip' ; Type = '...' },
  [pscustomobject] @{ Name = 'Amma 2.1.2.3.zip' ; Type = '...' }

# Define the regex that matches the full name
# and captures the embedded version number in named capture group 'version'.
# Better to use '...' (single quotes) to define regexes, to prevent
# confusion with string expansion inside "..."
# Note the alternate syntax `<version>` instead of `'version'`.
$regex = '^Amma\s(?<version>(\d+\.){3}\d+)\.zip$'

# Filter by the line of interest, then sort by the extracted version number.
# Automatic variable $Matches is a hashtable that contains the results of
# the regex match, with entry 'version' containing the capture group's value. 
# Casting to [version] ensures that version-appropriate sorting is used.
$wholeContent |
  Where-Object { $_.Name -match $regex } | 
    Sort-Object { [version] ($_.Name -replace $regex, '${version}') }

Обратите внимание, что здесь требуется дважды [1] : один раз для фильтрации интересующих строк и еще раз для извлечения текста встроенной версии через -replace operator .

Примечание: здесь возможно использование -replace с исходным регулярным выражением, поскольку имеющееся регулярное выражение соответствует входной строке целом , который позволяет заменить всю строку только значением именованной группы захвата (${version}), чтобы получить только последнее; более многословная альтернатива заключается в использовании другой операции -match для получения значения группы захвата с помощью $Matches:
$null = $_.Name -match $regex; $Matches['version']

Выше приведено следующее, показывающее, что только строки интерес был извлечен, правильно отсортирован по номеру версии:

Name              Type
----              ----
Amma 1.0.0.2.zip  ...
Amma 2.1.2.3.zip  ...
Amma 10.0.0.1.zip ...

[1], а automati c $Matches переменная , заполненная -match операция, - это , доступная в блоках сценария в последующих сегментах конвейера, в принципе, позволяющая получить доступ к результатам операции сопоставления, она не может использоваться здесь, потому что Sort-Object является необходимостью агрегирования командлет; то есть он должен сначала собрать все входные данные , чтобы выполнить сортировку, и в этот момент использование $Matches в вычисляемом свойстве содержит только last совпадений входного объекта.

0 голосов
/ 19 января 2020

Простой пример сортировки по совпадению регулярного выражения по последнему символу.

echo a3 b2 c1 | sort { $_ -match "(?'last'.$)"; $matches.last }                                               

c1
b2
a3
...