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: 하위 표현식 연산자 $( )

또한 또는 루프 Get-ChildItem내에서 동일한 위치에 사용하는 것을 피해야 합니다 . 귀하의 예에서는 동일한 항목에 대해 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)
}

관련 정보