Используйте оператор -cmatch
для регистрозависимого сопоставления с регулярным выражением ( регулярное выражение ):
Get-Content .\out.txt | Where-Object { $_ -cmatch '^\p{Lu}+$' }
-cmatch
- регистрчувствительный вариант оператора -match
(псевдоним которого -imatch
);учитывая, что -match
не чувствителен к регистру, -cmatch
должен использоваться для обнаружения различий в регистре.
\p{Lu}
соответствует одному символу в верхнем регистре - включая символы без ASCII с ударениемнапример, Ü
[1] - и добавление +
соответствует одному или нескольким подряд.Заключение выражения в ^
(начало строки) и $
(конец строки) означает, что сопоставляются только строки, полностью состоящие из заглавных букв.
- Ansgar Wiechers предлагает
-cnotmatch '\p{Ll}'
вместо этого, что работает немного по-другому: это исключило бы строки, содержащие хотя бы один строчный символ, что означает, что строки сохраняются, даже если они (также) содержат небуквенные символы (до тех пор, покапоскольку здесь нет строчных букв).
Альтернатива с Select-String
, которая может работать лучше:
Select-String -CaseSensitive '^\p{Lu}+$' .\out.txt | Select-Object -ExpandProperty Line
Select-String
также не чувствительна к региструпо умолчанию (как и PowerShell в целом), поэтому здесь требуется переключатель
-CaseSensitive
.
Обратите внимание, что, несмотря на свое название, Select-String
начиная с PowerShell Core 6.1.0 не поддерживаетвывод согласованных линий напрямую;вместо этого он выводит объекты информации о совпадении, свойство .Line
которых содержит совпавшую строку, поэтому необходимо Select-Object -ExpandProperty Line
.
В этом выпуске GitHub предлагается добавить новый параметр переключателя для поддержки прямого выводасоответствующие строки.
Что касается того, что вы пытались :
Код, выполняемый командлетом ForEach-Object
, должен быть передан как сценарий block - т. е. фрагмент кода, заключенный в { ... }
.
. Вы пренебрегли этим, что вызвало синтаксическую ошибку, которую вы видели.
Кроме того, тип [string]
(строка .NET) не имеет метода .IsUpper()
(и даже если он есть, вы забыли ()
после .IsUpper
).
Только тип [char]
имеет .IsUpper()
метод, а именно static , который вы можете вызвать следующим образом: [char]::IsUpper('A')
- но вам придется вызывать этот метод в цикле для каждого символа в вашей входной строке:
Get-Content .\out.txt | Where-Object {
foreach ($c in $_.ToCharArray()) { if (-not [char]::IsUpper($c)) { return $False } }
$True
}
Наконец, не используйте Write-Host
для возврата результатов - Write-Host
распечатки только на консоли - yВы не сможете перехватить или перенаправить такой вывод [2] .Вместо этого используйте Write-Output
или, что еще лучше, полагайтесь на неявное поведение PowerShell: простое использование $_
в качестве собственного оператора выведет его - любое выражение или команда, которую вы не захватываете и не перенаправляете, автоматическиoutput (отправляется в поток вывода об успешном завершении).
[1] Напротив, при использовании выражения диапазона символов [A-Z]
распознаются только символы верхнего регистра ASCII (английский).
[2] Никогда в PSv4-, но с дополнительными усилиями вы можете в PSv5 + - но дело в том, что Write-Host
не предназначен для вывода результатов (данных).