我有一个生成的报告文件,并包含各种文件引用。 我正在使用Select-String和正则表达式匹配某些类型的文件,并对它们执行后续处理。
我遇到的困境是在零(0),一(1)或多于一(2+)个匹配时始终确定匹配的数量。这是我尝试过的:
(select-string -path $outputfilePath -pattern $regex -allmatches).matches.count
如果有0个匹配则返回“null”,如果匹配则返回“1”,如果多个匹配则返回“null”。
(select-string -path $outputfilePath -pattern $regex -allmatches).count
如果有0或1个匹配则返回“null”,如果匹配多个匹配则返回匹配数。
我对Powershell很新,但是我试图找到一种一致的方法来测试匹配的数量,无论是否有0,1或多于1的匹配。
答案 0 :(得分:6)
试试这个:
$content = Get-Content $outputfilePath
($content -match $regex).Count
Powershell拥有许多Comparison Operators,可能会让您的生活更轻松。这是一个快速列表:
-eq
-ne
-gt
-ge
-lt
-le
-Like
-NotLike
-Match
-NotMatch
-Contains
-NotContains
-In
-NotIn
-Replace
在这种情况下,-Match
将$ content字符串与正则表达式$ regex匹配,输出按括号分组。此分组是字符串的集合。然后我们可以计算对象并打印出准确的匹配数。
那么为什么你的代码不按预期工作?当您进行单个匹配时,.Matches
实际上会返回一个System.Text.RegularExpressions.Match对象,对于字符串“test123”,该对象看起来像这样:
Groups : {test123}
Success : True
Captures : {test123}
Index : 15
Length : 7
Value : test123
为什么会这样?因为Microsoft.PowerShell.Commands.MatchInfo对象是Select-String
返回的对象。您可以通过在单匹配输出上尝试其他属性(例如.Filename
)来验证这一点。
好的,但为什么我们不能一次性获得所有比赛?这是因为多个匹配将返回多个对象,因此现在您有一个正在尝试操作的集合。该集合具有不同的类型,并且不理解.Matches
。 1匹配不返回任何集合,而是理解.Matches
的单个对象是!
长话短说:这些不是您正在寻找的输出!
答案 1 :(得分:2)
您可以使用array sub-expression operator @(...)
始终将结果放入包含Count
的集合中:
(Select-String ...) # may return $null, one match, or a collection of matches
(Select-String ...).Count # only succeeds for two or more matches
@(Select-String ...) # always returns a collection of matches
@(Select-String ...).Count # always succeeds