Чтобы сопоставить шаблоны с подстановочными знаками (например, *SALES BANKED*
), вам необходим оператор -like
;напротив, -contains
выполняет равенство сравнений (неявное -eq
с каждым элементом массива).
В то время как эти операторы (наряду с другими, например * 1015)* и -match
) поддерживают массив значений input [1] , операнд сравнения (обычно RHS) должен быть скаляр (одно значение) - вы не можете сравнивать входной массив с несколькими значениями одновременно.
InВ вашем сценарии лучше всего использовать регулярные выражения ( регулярные выражения ) вместо подстановочных выражений и объединить их в одиночное регулярное выражение с оператором чередования (|
), поэтому вы можете использовать одну операцию -match
для проверки нескольких шаблонов:
# Sample input
$UNREC_S0 = [pscustomobject] @{ Description = 'A SALES BANKED baz' },
[pscustomobject] @{ Description = 'bar' },
[pscustomobject] @{ Description = 'STORE TRANFrom foo' },
[pscustomobject] @{ Description = 'unrelated' }
# The filtering criteria: *regexes* to match against the descriptions,
# combined into a single regex with the alternation operator, '|'
$AutoJournalDescriptions = '^STORE TRANFrom ', 'SALES BANKED' -join '|'
# Construct script blocks to use with `Where-Object` below.
$NonAutoJournalCompanies = { $_.Description -notmatch $AutoJournalDescriptions }
$AutoJournalCompanies = { $_.Description -match $AutoJournalDescriptions}
$UNREC_S0 | Where-Object $NonAutoJournalCompanies | Export-Csv \\774512-LRBSPT01\*****$\uardata\rt1\BankRec\Test\step1\TestNonAutoJournal.txt -notype
# ...
Вышеприведенные данные приводят следующие данные CSV, показывая, что только описания не соответствующие регулярные выражения были экспортированы:
"Description"
"bar"
"unrelated"
Обратите внимание, как регулярное выражение ^STORE TRANFrom
соответствует wildcaВыражение rd STORE TRANFrom *
и SALES BANKED
до *SALES BANKED*
.
Подстановочный оператор *
- который обычно соответствует .*
в регулярном выражении - не требуется в регулярных выражениях здесь, потому чтоОператор -match
неявно выполняет сопоставление подстроки (тогда как сопоставление с подстановочными знаками с -like
сопоставляется с целом строкой ввода).
Необязательное чтение: фильтрациямассив строковых значений в виде массива подстрок или шаблонов:
Если вы сформулируете свои критерии как регулярные выражения (регулярные выражения), вы можете использовать Select-String
cmdlet , который поддерживает поддержку нескольких операндов сравнения:
# Sample input
$descriptions = 'A SALES BANKED baz', 'bar', 'STORE TRANFrom foo', 'unrelated'
# The filtering criteria: *regexes* to match against the descriptions.
$descriptionRegexes = '^STORE TRANFrom ', 'SALES BANKED'
($descriptions | Select-String -Pattern $descriptionRegexes).Line
Примечание: Вы можете также использовать эту технику для нахождения литеральных подстрок с помощьюиспользуя -SimpleMatch
вместо -Pattern
, но обратите внимание, что подстроки затем сопоставляются в любом месте в каждой входной строке, не имея возможности ограничить совпадение, скажем, с началом строки.
Выше приведен вывод following (массив из 2 элементов):
A SALES BANKED baz
STORE TRANFrom foo
Вы можете использовать аналогичный подход путем объединения отдельных регулярных выражений в один с чередованием (|
) оператор , который позволяет использовать оператор -match
:
# Sample input
$descriptions = 'A SALES BANKED baz', 'bar', 'STORE TRANFrom foo', 'unrelated'
# The filtering criteria: *regexes* to match against the descriptions,
# combined into a single regex with the alternation operator, '|'
$descriptionRegex = '^STORE TRANFrom ', 'SALES BANKED' -join '|'
# -> '^STORE TRANFrom |SALES BANKED'
$descriptions -match $descriptionRegex
Вы также можете адаптировать этот подход к буквенной подстроке соответствие , а именно экранирование подстрок для буквального использования внутри регулярного выражения с [regex]::Escape()
;например,
$descriptionRegex = ('yes?', '2.0').ForEach({ [regex]::Escape($_) }) -join '|'
В противном случае, , если вам нужна поддержка подстановочный знак , вам придется - неэффективно - циклы вложений (см. Ярлык ниже, если вы можете сделать определенные предположения):
# Sample input
$descriptions = 'A SALES BANKED baz', 'bar', 'STORE TRANFrom foo', 'unrelated'
# The filtering criteria: wildcard patterns to match against the descriptions.
$descriptionWildcards = 'STORE TRANFrom *', '*SALES BANKED*'
foreach ($descr in $descriptions) {
foreach ($wildcard in $descriptionWildcards) {
if ($descr -like $wildcard) { $descr; break }
}
}
Обратите внимание, что я использовал foreach
операторов вместо конвейера с ForEach-Object
командлет вызов;первый работает быстрее, последний может поддерживать постоянное потребление памяти, если ввод потоковый ;с массивами, уже находящимися в памяти, полностью, оператор foreach
является лучшим выбором.
Вы можете использовать ярлык , ЕСЛИ вы можете сделать два предположения :
Нет совпадений с одним шаблоном более чем один ввод.
Порядок ввода не должен бытьсохранились;то есть допустимо, чтобы порядок вывода описаний отражал порядок записей в массиве шаблонов, а не порядок описаний ввода.
# Sample input
$descriptions = 'A SALES BANKED baz', 'bar', 'STORE TRANFrom foo', 'unrelated'
# The filtering criteria: wildcard patterns to match against the descriptions.
$descriptionWildcards = 'STORE TRANFrom *', '*SALES BANKED*'
# Loop over the criteria and match the descriptions against each.
# `foreach` is the built-in alias for the `ForEach-Object` cmdlet.
# The output order will be reflect the order of the wildcard patterns.
$descriptionWildcards | foreach { $descriptions -like $_ }
В этомВ случае, когда результирующие элементы одинаковы, их порядок отличается:
STORE TRANFrom foo
A SALES BANKED baz
[1] С массивом значений в качестве входных данных эти операторы действуют как filters : то есть они возвращают подмассив соответствующих значений;например, 1, 2, 3 -eq 2
возвращает 2
в виде одноэлементного массива.