Похоже, вы ошиблись, предполагая, что оператор -contains
PowerShell выполнит подстроку , сопоставив с элементами массива LHS.
Вместо этого он выполняет равенство тесты - как и -eq
- против элементов массива - подробности см. в этом ответе .
Чтобы выполнил буквальное сопоставление подстроки с элементами массива , используйте:
# With non-literal search strings:
[bool] $contains = $group -match ([regex]::Escape($someString))
# With a string literal that doesn't contain regex metachars.,
# escaping isn't needed.
[bool] $contains = $group -match 'foo'
# With a string literal with metachars., you must individually \-escape them.
[bool] $contains = $group -match 'foo\.bar'
Примечание:
Вышеприведенный пример демонстрирует надежный общий способ убедиться, что строка поиска обрабатывается как литерал , используя [regex]::Escape()
, что необходимо, поскольку -match
ожидает регулярное выражение ( регулярное выражение ) в качестве его RHS (шаблон поиска) .
Бегство не всегда необходимо; в частности, это требуется только для присутствия так называемых метасимволов (имеющих специальное значение в регулярном выражении, таких как .
), а когда вы используете строку литерал , вы можете выбрать напрямую \
- уберечь их; например, чтобы искать буквальную подстроку a.b
, вы можете передать 'a\.b'
.
- Скорее всего, имена групп AD не требуют экранирования, но важно осознавать необходимость этого вообще.
Как и для всех операторов в PowerShell, по умолчанию сопоставление не учитывает регистр ; используйте вариант -cmatch
для сопоставления с учетом регистра.
Ограниченный выше тип [bool]
используется для гарантии того, что результат операции -match
будет преобразован в логическое значение:
- Хотя
-match
напрямую возвращает логическое значение с скалярным (не массивом) LHS, с массивом LHS оно действует как фильтр и возвращает соответствующие элементы массива вместо ; интерпретируется в булевом контексте, например в условном if
, который обычно все еще дает ожидаемый результат, поскольку непустой массив интерпретируется как $true
, а пустой - как $false
; опять же, однако важно знать разницу.
На практике это редко вызывает проблемы с производительностью, но стоит отметить, что -match
, действуя как фильтр с массивами, всегда совпадает с всеми элементами массива - он не останавливается при обнаружении совпадения first , как это делают операторы -contains
и -in
.
- Что касается плюса, вы можете использовать
-match
для получения соответствующих элементов.
Ошибочное ожидание -contains
выполнения подстроки , возможно, возникло из-за путаницы с одноименным, но не связанным String.Contains()
методом , который действительно выполняет буквальное совпадение подстроки ; например, 'foo'.Contains('o')
дает $true
. Также обратите внимание, что .Contains()
по умолчанию чувствителен к регистру .
PowerShell имеет оператор без для литерала соответствия подстроки.
Однако вы можете объединить универсальные функции фильтрации массивов PowerShell со строковым методом .Contains()
, но учтите, что обычно он работает (потенциально намного) хуже, чем -match
.
Достаточно производительная альтернатива - использовать метод массива PSv4 + .Where()
следующим образом:
# Note: Substring search is case-sensitive here.
[bool] $contains = $group.Where({ $_.Contains("string") }, 'First')
С положительной стороны этот подход прекращает сопоставление, как только найдено первое совпадение.