Powershell: оператор match возвращает true, но $matches равно null

Я работаю с регулярным выражением для соответствия содержимому файла:

> (get-content $_) -match $somePattern
the line of text that matches the pattern

это возвращает true, соответствие, однако моя переменная $matches остается пустой.

> $matches -eq $null
True

Не должны ли $match иметь в нем группы соответствия?

Ответ 1

Строго говоря, string -match ... и collection -match ... - два разных оператора. Первый получает значение Boolean и заполняет $matches. Второй получает каждый элемент коллекции, который соответствует шаблону и, по-видимому, не заполняет $matches.

Ваш пример должен работать так, как вы ожидаете, если файл содержит одну строку (работает первый оператор). Если файл содержит 2+ строки, используется второй оператор и $matches не установлен.

То же самое верно для других булевых операторов, применяемых к коллекции. То есть collection -op ... возвращает элементы, где item -op ... - true.

Примеры:

1..10 -gt 5 # 6 7 8 9 10
'apple', 'banana', 'orange' -match 'e' # apple, orange 

Булевы операторы, применяемые к коллекциям, удобны при правильном использовании. Но они могут сбивать с толку и приводить к ошибкам:

$object = @(1, $null, 2, $null)

# "not safe" comparison with $null, perhaps a mistake
if ($object -eq $null) {
    '-eq gets @($null, $null) which is evaluated to $true by if!'
}

# safe comparison with $null
if ($null -eq $object) {
    'this is not called'
}

Другой пример с -match и -notmatch может показаться запутанным:

$object = 'apple', 'banana', 'orange'

if ($object -match 'e') {
    'this is called'
}

if ($object -notmatch 'e') {
    'this is also called, because "banana" is evaluated to $true by if!'
}

Ответ 2

У меня была та же проблема, и точные строки работали из командной строки Powershell, но не из PowerShell ISE или обычной командной строки. Если вы не хотите перебирать все строки файла один за другим с помощью foreach, вы можете просто преобразовать это в строку, подобную этой, и она должна работать тогда:

if([string](Get-Content -path $filePath) -match $pattern)
{
   $matches[1]
}