- 包含或 - 匹配多个值
Posted
技术标签:
【中文标题】- 包含或 - 匹配多个值【英文标题】:-contains or -match several values 【发布时间】:2018-03-08 22:23:51 【问题描述】:我必须通过某些字符串过滤我的结果,并尝试使用 -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
【问题讨论】:
相关(-Contains
(集合运算符)、-match
/-imatch
(正则表达式匹配)和-like
/-ilike
(类SQL匹配)之间的区别):PowerShell and the -contains operator
【参考方案1】:
为什么它不能使用多个值?
因为这些运算符旨在针对单个参数进行测试,简单明了。
在单个操作中匹配多个参数的能力会引出一个问题:“输入是否需要满足 all 或 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
【讨论】:
为什么是非捕获组?简单地加入字符串也应该起作用。不过,我建议转义单个字符串。 当您以编程方式构建正则表达式时,您应该始终转义字符串。$filterPattern = '(?:0)' -f (($filterArray |% [Regex]::Escape($_) ) -join '|')
【参考方案2】:
使用数组作为-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($_)
【讨论】:
以上是关于- 包含或 - 匹配多个值的主要内容,如果未能解决你的问题,请参考以下文章