Powershell 正则表达式 Matches[0].Groups 与 Matches.Groups 基于键名的索引

Ist*_*115 4 regex powershell

我刚刚在 PowerShell 中遇到了这种奇怪的行为,我想知道是否有任何合理的解释:

在字符串上运行正则表达式匹配后:(
是的,我知道,这可能不是最好的方法,但是在构建管道时出现了问题,在这里我只提供了一个仍然表现出行为的精简最小示例.)

    $r = "asdf" | Select-String "(?<test>\w+)"
Run Code Online (Sandbox Code Playgroud)

以下两个表达式为我打印相同的结果:

    $r.Matches.Groups
    $r.Matches[0].Groups
Run Code Online (Sandbox Code Playgroud)

但在这两者中,只有第二个有效:

    $r.Matches.Groups['test'] 
    $r.Matches[0].Groups['test']
Run Code Online (Sandbox Code Playgroud)

最奇怪的是,如果我使用数字索引,它在两种情况下都有效。

    $r.Matches.Groups[0] 
    $r.Matches[0].Groups[0] 
Run Code Online (Sandbox Code Playgroud)

编辑:我知道在这个示例中捕获组根本没有必要,但我只想展示一个简单的示例来说明问题。最初,我正在使用具有多个捕获组的多个模式,我想通过名称访问它们。我知道我可以通过使用来解决它Matches[0],但我对解释感兴趣。

Mat*_*sen 6

这是因为 PowerShell 的一项名为“属性枚举”的功能。

从 PowerShell 4.0 开始,每当引用集合类型上不存在的成员时,PowerShell 将枚举该集合并调用每个项目上的成员。

这意味着这个表达式:

$g = $r.Matches.Groups
Run Code Online (Sandbox Code Playgroud)

...基本上与以下相同:

$g = foreach($match in $r.Matches){
    foreach($group in $match.Groups){
        $group
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,此时,$g不再是 a GroupCollection- 它只是 中任何匹配的任何组中的值的数组$r.Matches

这也解释了[0]索引表达式起作用的原因 - 可以很好地对常规数组进行索引。