我刚刚在PowerShell中遇到了这种奇怪的行为,我想知道是否有任何合乎逻辑的解释:
在字符串上运行正则表达式匹配后:
(是的,我知道,这可能不是最好的方法,但是在构建管道时出现问题,在这里我只提供一个精简的最小示例,该示例仍然表现出该行为。
$r = "asdf" | Select-String "(?<test>w+)"
以下两个表达式为我打印相同的结果:
$r.Matches.Groups
$r.Matches[0].Groups
但在这两个中,只有第二个有效:
$r.Matches.Groups['test']
$r.Matches[0].Groups['test']
最奇怪的是,如果我使用数字索引,它在两种情况下都有效。
$r.Matches.Groups[0]
$r.Matches[0].Groups[0]
编辑:我知道在这个例子中,捕获组根本不是必需的,但我只想展示一个简单的例子来说明一个问题。最初,我正在使用具有多个捕获组的多个模式,我想按名称访问这些模式。我知道我可以通过使用Matches[0]
来解决它,但我对解释感兴趣。
这是因为称为属性枚举的PowerShell功能。
从 PowerShell 4.0 开始,每当引用集合类型上不存在的成员时,PowerShell 都会枚举集合并调用每个项上的成员。
这意味着此表达式:
$g = $r.Matches.Groups
。基本同:
$g = foreach($match in $r.Matches){
foreach($group in $match.Groups){
$group
}
}
因此,此时,$g
不再是GroupCollection
- 它只是$r.Matches
中任何匹配项中任何组中任何组中的值的数组。
这也解释了为什么[0]
索引表达式有效 - 常规数组可以很好地索引到。