- Если вы не застряли с PowerShell v2, проще и эффективнее использовать
Get-Content -Raw
для чтения всего файла в виде одной строки;кроме того, Out-String
добавляет дополнительную строку в строку. - Поскольку вы ищете только первое совпадение , вы можете использовать оператор
-match
- нет необходимости в Select-String
s -AllMatches
переключатель. - Примечание. Хотя вы можете использовать
Select-String
без него, более эффективно использовать оператор -match
, если вы уже прочитали весь файл в память.
- Соответствие регулярному выражению по умолчанию всегда регистр- нечувствителен в PowerShell, что соответствует общей нечувствительности к регистру PowerShell.
Таким образом, следующее возвращает первый блок, еслиany:
if ((Get-Content -Raw $changelog) -match '(?m)^v\d+\.\d+\.\d+.*(\r?\n-\s?.*)+') {
# Match found - output it.
$Matches[0]
}
* (?m)
включает опцию встроенного регулярного выражения m
(многострочный), что приводит к тому, что якоря ^
и $
соответствуют началу и концу отдельные строки , а не строки в целом.
* \r?\n
соответствует как CRLF, так и символам новой строки только для LF.
* Вы можете сделать регулярное выражение немного более эффективным, сделав подвыражение (...)
без захвата , учитывая, что вам не интересно, что он захватил: (?:...)
.
Обратите внимание, что -match
само по себе возвращает Boolean (сскалярная LHS), но информация о матче записывается вавтоматические $Matches
переменные хеш-таблицы, чья запись 0
содержит общее совпадение.
Что касается то, что вы пытались :
'([Vv][0-9]+\.[0-9]+\.[0-9]+\n)(^-.*$\n)+'
неработать, потому что по умолчанию $
совпадает только в самом конце входной строки, в конце последней строки (хотя, возможно, до последней новой строки).Чтобы $
соответствовал концу каждой строки , вам нужно включить опцию многострочного регулярного выражения (что вы сделали во второй попытке).В результате, ничто не соответствует.
'(?smi)([Vv][0-9]+\.[0-9]+\.[0-9]+\n)(^-.*$\n)+'
не работает должным образом, потому что, используя опцию s
(однострочный), вы сделали .
match и новые строки тоже , так что жадное подвыражение, такое как .*
, будет соответствовать остатку строки через строки .В результате все с первого блока на матчах.