我正在尝试遍历使用字母日期命名的文件,并相应地设置文件日期时间。我的代码工作正常,当我注意到这个问题时,我已经准备好认为它是完整的。我的代码应该检测两个日期并生成错误,但它没有。我已经提取了相关代码,并重新创建了问题:
$str = "test20001231 20170415.txt"
$match = ($str -match "(?<=\b|\D)20\d{6,6}(?=\b|\D)")
"$match"
"$($Matches.length)"
"$($Matches[0].ToString())"
给出这个输出:
True
1
20001231
我对正则表达式代码的理解是,它应该匹配所有以 20 开头的 8 位数字,无论它在字符串中的任何位置,除非它在另一个数字之后或之前。所以我期望 $Matches.length 为 2。
我已经在网上的许多地方测试了正则表达式代码,它与我期望的两个日期相匹配:
http://regexstorm.net/tester?p=%28%3f%3c%3d%5cb%7c%5cD%2920%5cd%7b6%2c6%7d%28%3f%3d%5cb%7c%5cD%29&i=test20001231+20170415.txt
http://www.phpliveregex.com/p/jLA
该问题适用于 PS 和 PS ISE。我搜索了很多(我认为),但没有发现任何有用的东西。
有什么建议?
提前谢谢了,
戴夫
最佳答案
PowerShell 的 -match
运算符只查找每个输入字符串的第一个匹配项(如果有) ,因为它的目的是测试(任何)匹配项,而不管是否有多个匹配项。
注意单-match
表达式可以有多个输入字符串,如果 LHS 是一个数组,则返回匹配元素的数组;例如:'foo', 'bar', 'baz' -match 'b'
产生数组 'bar', 'baz'
.但是,对于每个数组元素,仅再次测试单个匹配项,并且自动 $Matches
在这种情况下不填充变量 - 见底部。
下面的所有命令都假定 PSv3+,但也可以在 v2 中运行。
您需要使用 .NET 框架的 [regex]
获取多个匹配项的类 :
PS> ([regex]::Matches('test20001231 20170415.txt', '(?<=\b|\D)20\d{6,6}(?=\b|\D)')).Value
20001231
20170415
[regex]::Matches()
输出 [System.Text.RegularExpressions.Match]
的集合实例[1] 其.Value
属性包含匹配项。注意如何
.Value
应用于整个合集,在 PSv3+ 中自动将集合成员的属性值作为数组返回。
要获得匹配的数量:
PS> ([regex]::Matches('test20001231 20170415.txt', '(?<=\b|\D)20\d{6,6}(?=\b|\D)')).Count
2
另一种选择是使用
Select-String -AllMatches
,输出 [Microsoft.PowerShell.Commands.MatchInfo]
实例谁的
.Matches
属性包含每行的集合 [System.Text.RegularExpressions.Match]
实例:PS> ('test20001231 20170415.txt' |
Select-String -AllMatches '(?<=\b|\D)20\d{6,6}(?=\b|\D)').Matches.Value
20001231
20170415
如上,代入.Count
为 .Value
输出匹配的数量。注意使用
Select-String
使用单个输入字符串 有点笨拙,但它是 用于大型输入集合的正确工具 ,例如文件的行。选读:自动
$Matches
变量:自动
$Matches
变量已填充(从 PSv5.1 开始):-match
时运算符(operator) $Matches
既不填充也不重置。 -match
返回 $true
)-match
返回 $false
),一个预先存在的 $Matches
值(如果有)保持不变。 $Matches
是 [hashtable]
具有以下条目的实例:0
的条目是整个匹配项 - 根据定义,此键始终存在。 <n>
的条目是 - 未命名 - 带有索引的捕获组 <n>
匹配。 <name>
的条目是命名捕获组 <name>
匹配。 事实
$Matches
(可能)还包含捕获组值证明其复数名称合理 - 尽管仅与给定正则表达式的单个匹配有关。[1] 要检查单个对象的类型或集合元素的类型,请通过管道发送至 Get-Member :
([regex]::Matches('foo', 'o')) | Get-Member
要检查集合本身的类型,请将其传递给 Get-Member -InputObject
:Get-Member -InputObject ([regex]::Matches('foo', 'o'))
关于regex - PowerShell regex -match 只匹配一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43421755/