-包含或匹配多个值
-contains or -match several values
我必须按某些字符串过滤我的结果,并尝试使用 -match
和 -contains
。
-match
如果我只有一个值要过滤而不是数组,则可以工作。
-contains
既不适用于一个字符串,也不适用于字符串数组。
为什么它不能使用多个值?特别是-contains
。或者有其他简单的方法可以解决吗?
$Folder = 'C:\Test'
$filterArray = @('2017-05', '2017-08')
$filter = '2017-05'
## test with -MATCH
## working with one match string
Get-ChildItem -Path $Folder -Recurse -Include *.txt |
Where { $_.FullName -match $filter } |
ForEach-Object { $_.FullName }
## NOT working with match string array - no results
Get-ChildItem -Path $Folder -Recurse -Include *.txt |
Where { $_.FullName -match $filterArray } |
ForEach-Object { $_.FullName }
## test with -CONTAINS
## NOT working with one contains string - no results
Get-ChildItem -Path $Folder -Recurse -Include *.txt |
Where { $_.FullName -contains $filter } |
ForEach-Object { $_.FullName }
## NOT working with contains string array- no results
Get-ChildItem -Path $Folder -Recurse -Include *.txt |
Where { $_.FullName -contains $filterArray } |
ForEach-Object { $_.FullName }
Why isn't it working with several values?
因为这些运算符旨在针对单个参数进行测试,简单明了。
在单个操作中匹配多个参数的能力会引出一个问题:“输入是否需要满足 all 或 any 参数条件"?
如果你想测试与正则表达式模式数组的 any 的匹配,你可以使用非捕获组从它们构造一个模式,如下所示:
$filterPattern = '(?:{0})' -f ($filterArray -join '|')
Get-ChildItem -Path $Folder -Recurse -Include *.txt | Where {$_.FullName -match $filterPattern} | ForEach-Object{ $_.FullName }
您也可以完全删除 Where-Object
和 ForEach-Object
循环,因为 PowerShell 3.0 支持 属性 枚举:
(Get-ChildItem -Path $Folder -Recurse -Include *.txt).FullName -match $filterPattern
使用数组作为 -match
或 -contains
运算符的第二个操作数不起作用。您基本上可以采用两种方法:
从数组构建正则表达式并将其与 -match
运算符一起使用:
$pattern = @($filterArray | ForEach-Object {[regex]::Escape($_)}) -join '|'
... | Where-Object { $_.FullName -match $pattern }
这是首选方法。
使用嵌套的 Where-Object
过滤器和 String.Contains()
方法:
... | Where-Object {
$f = $_.FullName
$filterArray | Where-Object { $f.Contains($_) }
}
我必须按某些字符串过滤我的结果,并尝试使用 -match
和 -contains
。
-match
如果我只有一个值要过滤而不是数组,则可以工作。
-contains
既不适用于一个字符串,也不适用于字符串数组。
为什么它不能使用多个值?特别是-contains
。或者有其他简单的方法可以解决吗?
$Folder = 'C:\Test'
$filterArray = @('2017-05', '2017-08')
$filter = '2017-05'
## test with -MATCH
## working with one match string
Get-ChildItem -Path $Folder -Recurse -Include *.txt |
Where { $_.FullName -match $filter } |
ForEach-Object { $_.FullName }
## NOT working with match string array - no results
Get-ChildItem -Path $Folder -Recurse -Include *.txt |
Where { $_.FullName -match $filterArray } |
ForEach-Object { $_.FullName }
## test with -CONTAINS
## NOT working with one contains string - no results
Get-ChildItem -Path $Folder -Recurse -Include *.txt |
Where { $_.FullName -contains $filter } |
ForEach-Object { $_.FullName }
## NOT working with contains string array- no results
Get-ChildItem -Path $Folder -Recurse -Include *.txt |
Where { $_.FullName -contains $filterArray } |
ForEach-Object { $_.FullName }
Why isn't it working with several values?
因为这些运算符旨在针对单个参数进行测试,简单明了。
在单个操作中匹配多个参数的能力会引出一个问题:“输入是否需要满足 all 或 any 参数条件"?
如果你想测试与正则表达式模式数组的 any 的匹配,你可以使用非捕获组从它们构造一个模式,如下所示:
$filterPattern = '(?:{0})' -f ($filterArray -join '|')
Get-ChildItem -Path $Folder -Recurse -Include *.txt | Where {$_.FullName -match $filterPattern} | ForEach-Object{ $_.FullName }
您也可以完全删除 Where-Object
和 ForEach-Object
循环,因为 PowerShell 3.0 支持 属性 枚举:
(Get-ChildItem -Path $Folder -Recurse -Include *.txt).FullName -match $filterPattern
使用数组作为 -match
或 -contains
运算符的第二个操作数不起作用。您基本上可以采用两种方法:
从数组构建正则表达式并将其与
-match
运算符一起使用:$pattern = @($filterArray | ForEach-Object {[regex]::Escape($_)}) -join '|' ... | Where-Object { $_.FullName -match $pattern }
这是首选方法。
使用嵌套的
Where-Object
过滤器和String.Contains()
方法:... | Where-Object { $f = $_.FullName $filterArray | Where-Object { $f.Contains($_) } }