PowerShell:如何在 Where-Object -MATCH 中将数组值替换为正则表达式

PowerShell:如何在 Where-Object -MATCH 中将数组值替换为正则表达式

-match在以下条件下,我无法从数组中获取字符串值并将其插入到正则表达式中Where-Object

$ordArr = @("001", "005", "002", "007")

for ($i = 0; $i -le $ordArr.Length) {
  get-childitem -file -recurse |
    where-object {$_.BaseName -match "^$ordArr[$i].*$"} |
      ForEach-Object {echo $_}

  $i = ($i + 2)
}

如果我要$ordArr[$i]自行输入(即在函数之外调用它Where-Object,它会返回预期的字符串值。

我也尝试过

  • ... -match "^${ordArr[$i]}.*$ ... "
  • ... -match "^${ordArr[$[tick mark]{i[tick mark]}]}.*$ ... "

以及其他使用报价市场和括号的其他杂项组合。但是,我无法从$ordArr以及使用报价市场和括号的其他杂项组合。但是,我无法获取替换到命令中的

根据括号和刻度标记的组合,它要么不返回任何内容,要么返回所有内容。此外,如果我要手动将 中001的输入$ordArr到正则表达式中,... -match "^001.*$" ...那么它将返回我期望的文件。

那么,如何将数组中的值插入到正则表达式条件中Where-Object ... -match ...

谢谢!

答案1

您的正则表达式模式没有按照您的预期插入字符串。

"^$ordArr[$i].*$"}结果是^001 005 002 007[0].*$

你必须使用子表达式运算符 $()如果您想在字符串等另一个表达式中使用计算( $int1 + $int2)、成员访问($something.Path)、索引访问( )等表达式。$array[1]

在你的情况下,你必须把你的放入$ordArr[$i]子表达式中:

"^$($ordArr[$i]).*$"

看:MSFT:子表达式运算符 $( )

此外,您应避免在or循环Get-ChildItem内对同一位置使用。在您的示例中,您对同一项目递归调用了 4 次 Get-ChildItem。forforeach

我的建议

我的建议是定义一个组合正则表达式模式,而不是在数组上循环多次来构建模式。这比其他方法快得多。

$ordArr = @('001', '005', '002', '007')

# build a combined regex pattern 
#   this time we don't need a subexpression operator, since we don't access any member or index from $_
$regexPattern = ($ordArr | ForEach-Object { "^$_.*$" }) -join '|'

Get-ChildItem -File -Recurse | Where-Object {
    $_.BaseName -match  $regexPattern 

    # as alternative and to avoid saving anything to the automatic variable $matches (-> better performance)
    # but not idiomatic Powershell:
    # [regex]::IsMatch($_.BaseName, $regexPattern)
}

相关内容