我刚刚在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]
索引表达式为何起作用的原因-可以将常规数组建立索引。
关于regex - Powershell正则表达式Matches [0] .Groups与Matches.Groups基于键名的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61972136/