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]}]}.*$ ... "

和其他雜項。使用逐筆報價市場和大括號的組合。但是,我無法將 to 中的字串值$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中使用 for 相同位置。在您的範例中,您對相同的項目遞歸呼叫 Get-ChildItem 4 次。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)
}

相關內容