
У меня возникли проблемы с получением строкового значения из массива для вставки в выражение регулярного выражения в приведенном ниже -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: Оператор подвыражения $( )
Кроме того, следует избегать использования Get-ChildItem
for для одного и того же местоположения внутри цикла for
or foreach
. В вашем примере вы вызываете Get-ChildItem рекурсивно 4 раза для одних и тех же элементов.
Мое предложение
Мое предложение — определить комбинированный шаблон регулярных выражений, чтобы получить один вместо того, чтобы проходить несколько раз по массиву для построения шаблона. Это намного быстрее других подходов.
$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)
}