如何用PowerShell管道将Match[]转为GroupCollection[]避免枚举展开
PowerShell中Match[]转GroupCollection[]的管道实现问题
我通过字符串匹配得到Match[]数组,每个Match对象的Groups属性为GroupCollection类型。希望将Match[]映射为GroupCollection[],尝试用ForEach-Object通过管道实现时,返回$_.Groups会导致GroupCollection被枚举展开,丢失实例属性。如何通过管道实现该需求?测试代码如下:
$String = "12345" $Regex = "(?<number>\d)" $MatchArr = ($String | Select-String -Pattern $Regex -AllMatches).Matches # Match[] $DesiredOutput = $MatchArr[0].Groups, $MatchArr[1].Groups, $MatchArr[2].Groups # etc.. Get-Member -InputObject $DesiredOutput[0] # "GroupCollection" 👍 $WrongOutput = $MatchArr | ForEach-Object {$_.Groups} # Resolves and outputs the collection contents, making a flat array of all the contents Get-Member -InputObject $WrongOutput[0] # "Match" 👎 $WrongOutput[0] == $MatchArr[0].Groups[0], AKA the actual contents
解决方案
方法1:用逗号运算符封装集合
PowerShell默认会枚举集合输出元素,用逗号将GroupCollection包装为单元素数组,即可避免被展开,直接输出集合实例:
$CorrectOutput = $MatchArr | ForEach-Object { , $_.Groups } Get-Member -InputObject $CorrectOutput[0] # 返回"GroupCollection" ✅
逗号是PowerShell的数组构造运算符,这里创建仅包含当前GroupCollection的数组,管道会输出该数组的唯一元素(即GroupCollection实例),而非枚举其内部元素。
方法2:使用Write-Output -NoEnumerate
通过Write-Output的-NoEnumerate参数,强制直接输出集合实例而不枚举其元素:
$CorrectOutput = $MatchArr | ForEach-Object { Write-Output $_.Groups -NoEnumerate } Get-Member -InputObject $CorrectOutput[0] # 返回"GroupCollection" ✅
内容的提问来源于stack exchange,提问作者Khaled
相关产品推荐
相关产品推荐

