【问题标题】:Sort by named capture group within regular expression in powershell按PowerShell中正则表达式中的命名捕获组排序
【发布时间】:2020-05-05 09:05:30
【问题描述】:

我有一个正则表达式定义如下:

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

上面的表达式带有一个带有组的标签 - (\d+.){3}\d)

我使用它如下:

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

但我想改为按定义的正则表达式中的标记组对其进行排序,它表示版本号。

【问题讨论】:

  • 您需要重新计算管道 S-O 段中的计算属性。

标签: regex powershell sorting capture-group


【解决方案1】:

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]:一次过滤感兴趣的行,再次通过@987654322提取嵌入的版本文本@。

注意:这里可以使用 -replace 和原始正则表达式,因为手头的正则表达式旨在匹配 whole 输入字符串,它允许将整个字符串替换为命名捕获组的值 (${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] 虽然automatic $Matches variable-match 操作填充,原则上在后续管道段的脚本块中可用,允许访问匹配的结果操作,这里不能使用它,因为Sort-Object 必须是一个聚合 cmdlet;也就是说,它必须首先收集所有输入才能执行排序,此时在计算属性中使用$Matches仅包含最后一个输入对象的匹配项。支持>

【讨论】:

    【解决方案2】:

    按正则表达式匹配排序的简单示例,按最后一个字符。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-17
      • 2011-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-27
      • 1970-01-01
      相关资源
      最近更新 更多