2015-07-12 3 views
1

У меня есть массив строк, как:Исключить элементы массива на основе динамических критериев

  • File1
  • file2
  • File1_s1
  • File2_s1
  • печати $
  • PSDrive
  • PSParentPath

Мне нужно выбрать все строки, которые не соответствуют динамическому набору правил. Мне действительно не нужно fancy regex, я просто хочу сопоставить динамическое количество очень простых правил регулярных выражений. В принципе:

$Arr | Where {($_.Name -notlike '_s1') -and ($_.Name -notlike 'Print$')} 

Но мне нужно динамическое количество -ands, заданное входом функции. Есть ли простой способ сделать это?

+0

'' -like' и -notlike' не поддерживают регулярные выражения. – Matt

+0

Да ... Я знаю, они просто делают подстановочные матчи. Я хочу, чтобы указанное поведение нескольких простых совпадений подстановочных знаков, но их динамическое число. –

ответ

1

Ok, так что вы можете сделать это

$omits = "_s1","Print$" 
$regex = '({0})' -f (($omits | ForEach-Object{[regex]::Escape($_)}) -join "|") 

$arr | Where-Object{$_ -notmatch $regex} 

$omits будет содержать список строк, которые вы хотите -match/-notmatch. Затем мы берем каждый элемент и запускаем на нем регулярное выражение ($ - специальный символ регулярного выражения. Конец привязки строки). Возьмите каждую очищенную строку и создайте соответствующую группу. Таким образом, в приведенном выше примере $regex бы

(_s1|Print\$) 

Добавить больше записей в $omit, как вы считаете нужным. Что дало бы отфильтрованные результаты, как

File1 
File2 
PSDrive 
PSParentPath 

Если вы можете доверять, чтобы избежать собственного регулярного выражения ваших вариантов раскрыться больше.

$omits = "_s1","Print\$","^PS" 
$regex = '({0})' -f ($omits -join "|") 

Таким образом, PS должен находиться в начале строки.

+0

Отлично! В качестве продолжения, есть ли способ, используя этот метод, исключить записи, начинающиеся с PS? Просто добавляет PS в $ omits слишком широко, или это сработает? –

+0

В настоящее время он будет соответствовать любому месту в строке. Если вы хотите совместить позиционно, это будет легко, но вам придется избегать собственных строк. – Matt

+0

Извините, что вы беспокоитесь, но можете ли вы привести пример того, что вы имеете в виду? Я могу гарантировать, что $ omits ускользает должным образом. –

0

Как подсказывает @Matt, без подстановочных знаков в ваших строках -NotLike в основном эквивалентен -ne (и тогда вы могли бы просто использовать -NotIn). Я предполагаю, что на ваших примерах отсутствуют подстановочные знаки, но ваши фактические шаблоны не являются.

$patternArray = 'File1','File2','File1_s1','File2_s1','Print$','PSDrive','PSParentPath'; 
foreach ($pattern in $patternArray) { 
    $Arr = $Arr | Where-Object {$_.Name -notlike $pattern}; 
} 

Или вы могли бы сделать некоторые основные согласования с:

$patternArray = 'File1','File2','File1_s1','File2_s1','Print$','PSDrive','PSParentPath'; 
foreach ($pattern in $patternArray) { 
    $Arr = $Arr | Where-Object {$_.Name -notlike "*$pattern*"}; 
} 
+0

Думаю, я понимаю, что вы предлагаете, но поскольку это написано, это не имеет никакого смысла для меня.'File1', 'File2' и т. Д. $ Arr. Вы предполагаете, что $ patternArray будет массивом шаблонов, которые будут соответствовать ... например * _s1, * _s2? –

+0

@BryanWinstead Что вы не понимаете? Вы берете массив объектов, '$ Arr' и массив шаблонов. Затем для каждого шаблона вы удаляете элементы массива, соответствующие шаблону. Вы возвращаете результат в '$ Arr', так что в следующий раз, когда цикл запускает массив объектов, предыдущие шаблоны уже удалены. –

+0

Я сейчас _ Мэт? – Matt