仅过滤文件中的大写单词

Fra*_*ani 3 regex powershell foreach

我有一个output.txt文件,有大约1000个单词,如下所示:

SESSIONDAYOFWEEK
FILMTITLELONGALT
tblTrans_Ticket.
ADMITDETAILSALT2
MESSAGESTUB2ALT3
StartDayOfWeek
Description
MESSAGESTUB2ALT2
FILMTITLESHORTALT
Applications
TICKETTYPELONGALT

我需要过滤该文件,只选择只有大写字符的单词,并删除那些具有小写字符的单词.

我在PowerShell中运行此命令:

Get-Content .\out.txt | ForEach-Object if ($_.IsUpper) {Write-Host $_}
Run Code Online (Sandbox Code Playgroud)

并且shell逐个解析所有单词,每个单词打印我:

ForEach-Object : Input name "if" cannot be resolved to a method.
At line:1 char:25
+ ... et-Content .\out.txt | ForEach-Object if ($_.IsUpper) {Write-Host $_}
+                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (TAIL:PSObject) [ForEach-Object], PSArgumentException
    + FullyQualifiedErrorId : MethodNotFound,Microsoft.PowerShell.Commands.ForEachObjectCommand

我不明白我哪里错了?

mkl*_*nt0 5

使用-cmatch运算符对正则表达式(正则表达式)进行区分大小写的匹配:

Get-Content .\out.txt | Where-Object { $_ -cmatch  '^\p{Lu}+$' }
Run Code Online (Sandbox Code Playgroud)
  • -cmatch-match运算符的区分大小写的变体(别名是-imatch); 鉴于-match不区分大小写,-cmatch必须使用它来检测大小写区别.

  • \p{Lu}匹配单个大写字符 - 包括重音的非ASCII字符,如Ü[1] - 并+在一行中添加一个或多个匹配.将表达式括在^(字符串的开头)和$(字符串的结尾)意味着只匹配完全由大写字符组成的行.

    • -cnotmatch '\p{Ll}'相反,Ansgar Wiechers建议它的工作方式略有不同:它会消除包含至少一个小写字符的行,这意味着即使它们(也)包含非字母字符(只要没有小写字母),行也会被保留.

替代方案Select-String可能表现更好:

Select-String -CaseSensitive '^\p{Lu}+$' .\out.txt | Select-Object -ExpandProperty Line
Run Code Online (Sandbox Code Playgroud)

Select-String默认情况下也不区分大小写(一般来说是PowerShell),因此
-CaseSensitive这里需要切换.

请注意,尽管名称如此,但Select-StringPowerShell Core 6.1.0不支持直接输出匹配的行; 相反,它输出其.Line属性包含匹配行的匹配信息对象,因此需要Select-Object -ExpandProperty Line.
此GitHub问题建议添加新的switch参数以支持匹配字符串的直接输出.


至于你试过的:

ForEach-Objectcmdlet要执行的代码必须作为脚本块传递- 即包含在其中的一段代码{ ... }.

你忽略了那样做,这导致了你看到的语法错误.

此外,[string]类型(.NET字符串)没有.IsUpper()方法(即使它确实如此,你忘了()后面.IsUpper).

只有[char]类型有一个.IsUpper()方法,即静态方法,您可以按如下方式调用:[char]::IsUpper('A')- 但您必须在输入字符串中的每个字符的循环中调用此方法:

Get-Content .\out.txt | Where-Object { 
  foreach ($c in $_.ToCharArray()) { if (-not [char]::IsUpper($c)) { return $False } }
  $True
}
Run Code Online (Sandbox Code Playgroud)

最后,不要使用Write-Host返回结果 - Write-Host打印到控制台 - 您将无法捕获或重定向此类输出[2].相反,使用Write-Output或者更好地依赖PowerShell的隐式输出行为:简单地使用$_它自己的语句将输出它 - 任何既不捕获也不重定向的表达式或命令会自动输出(发送到成功输出流).


[1]相比之下,使用字符范围表达式[A-Z]只能识别ASCII范围(英语)大写字符.

[2]从未在PSv4中,但是你可以在PSv5 +中付出额外的努力 - 但重点Write-Host是不能用于输出结果(数据).