Regex 仅从文件中筛选大写单词
我有一个output.txt文件,大约有1000个单词,如下所示: SESSIONDAYOFWEEK FILMTITLELONGALT tblTrans_Ticket. ADMITDETAILSALT2 MESSAGESTUB2ALT3 StartDayOfWeek Description MESSAGESTUB2ALT2 FILMTITLESHORTALT Applications TICKETTYPELONGALT 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 ForEach对象:无法将输入名称“if”解析为方法。 第1行字符:25 + ... et内容。\out.txt | ForEach对象if($u0.IsUpper){Write Host$0} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +CategoryInfo:InvalidArgument:(尾部:PSObject)[ForEach Object],PSArgumentException +FullyQualifiedErrorId:MethodNotFound,Microsoft.PowerShell.Commands.ForEachObjectCommandRegex 仅从文件中筛选大写单词,regex,powershell,foreach,Regex,Powershell,Foreach,我有一个output.txt文件,大约有1000个单词,如下所示: SESSIONDAYOFWEEK FILMTITLELONGALT tblTrans_Ticket. ADMITDETAILSALT2 MESSAGESTUB2ALT3 StartDayOfWeek Description MESSAGESTUB2ALT2 FILMTITLESHORTALT Applications TICKETTYPELONGALT shell一个接一个地解析所有单词,每个单词都会打印我: ForEach-O
我不明白我哪里错了 使用
-cmatch
运算符对正则表达式()进行区分大小写的匹配:
是的区分大小写的变体(其别名为-cmatch
);鉴于-imatch
不区分大小写,因此必须使用-match
来检测大小写差异-cmatch
匹配单个大写字符-包括重音非ASCII字符,如\p{Lu}
[1]-并添加Ü
匹配一行中的一个或多个字符。将表达式包含在+
(字符串的开头)和^
(字符串的结尾)中意味着仅匹配完全由大写字符组成的行$
- 建议改为
,其工作原理稍有不同:它将删除至少包含一个小写字符的行,这意味着即使这些行(也)包含非字母字符(只要没有小写字母),也会保留这些行-cnotmatch'\p{Ll}'
- 建议改为
Select String
的替代方法可能会表现得更好:
Select-String -CaseSensitive '^\p{Lu}+$' .\out.txt | Select-Object -ExpandProperty Line
默认情况下,Select String
也不区分大小写(与PowerShell一般一样),因此此处需要使用-CaseSensitive
开关
请注意,尽管名称不同,PowerShell Core 6.1.0中的Select String
不支持直接输出匹配的行;相反,它输出匹配信息对象,这些对象的.Line
属性包含匹配的行,因此需要选择对象-ExpandProperty Line
建议添加一个新的开关参数以支持匹配字符串的直接输出
至于你所尝试的:
ForEach对象
cmdlet要执行的代码必须作为脚本块传递,即{…}
中包含的一段代码
您忽略了这一点,这导致了您看到的语法错误
另外,[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
}
最后,不要使用Write Host
返回结果-Write Host
仅打印到控制台-您将无法捕获或重定向此类输出[2]。相反,使用Write Output
,或者更好地依赖于PowerShell的隐式输出行为:只需将$\uU
作为自己的语句来输出即可-任何既不捕获也不重定向的表达式或命令都会自动输出(发送到成功输出流)
[1] 相比之下,使用字符范围表达式
[A-Z]
只能识别ASCII范围(英语)大写字符
[2] 从来没有在PSv4中使用过,但是如果在PSv5+中进行额外的努力,您可以使用它,但关键是
写主机
并不用于输出结果(数据)。最简单的方法可能是使用regex
Get-Content .\out.txt | Where-Object { $_ -cmatch "\b[A-Z0-9_]+\b" }
Where Object
充当过滤器,允许任何匹配项通过,并丢弃任何不匹配项
-cmatch
将进行区分大小写的正则表达式匹配
正则表达式解释:
+
量词-在一次和无限次之间进行匹配,尽可能多地匹配,根据需要返回(贪婪)
A-Z
介于A(索引65)和Z(索引90)之间的单个字符
0-9
介于0(索引48)和9(索引57)之间的单个字符
\u
按字面意思匹配字符\u
\b
在单词边界处断言位置
如果您不想允许带有这些字符的单词通过筛选器,则可以删除0-9
和
参见:你好,弗朗西斯科·曼托瓦尼 正如其他人提到的,
[string]
类型没有.IsUpper
属性。[char]
类型有一个.IsUpper()
方法,但它也缺少具有该名称的属性。[咧嘴笑]
您可以测试所有大写数组项,因此
$Collection.Where({$_ -ceq $_.ToUpper()})
希望有帮助,lee回答得很好,尽管排除带有小写字母的任何内容可能更简单,如
|?{$\u-cnotmatch'[a-z]}
Get-Content .\out.txt | Where-Object { $_ -cmatch "\b[A-Z0-9_]+\b" }
$Collection.Where({$_ -ceq $_.ToUpper()})