鉴于下面的代码,在0,2和4位也有匹配,因为b*
匹配空字符串。
PS C:\Users\admin> [regex]$regex = "ab*"
PS C:\Users\admin> $regex.Matches("ababab")
Groups : {0}
Success : True
Name : 0
Captures : {0}
Index : 0
Length : 2
Value : ab
Groups : {0}
Success : True
Name : 0
Captures : {0}
Index : 2
Length : 2
Value : ab
Groups : {0}
Success : True
Name : 0
Captures : {0}
Index : 4
Length : 2
Value : ab
我希望结果集能够包含匹配的a
的上述位置。
另外,请考虑以下示例:
PS C:\Users\admin> [regex]::Matches("aaaa", "aa?")
Groups : {0}
Success : True
Name : 0
Captures : {0}
Index : 0
Length : 2
Value : aa
Groups : {0}
Success : True
Name : 0
Captures : {0}
Index : 2
Length : 2
Value : aa
在这种情况下,每个位置都有匹配,但只报告两个结果。
如何让Powershell在每个位置都匹配正则表达式,以便所有匹配都包含在结果集中?
答案 0 :(得分:1)
在ab*
中,*
表示b
贪婪零或更多。它会尽可能匹配,这就是你得到ab
的原因。如果您只想要a
,请使用ab*?
使其变得懒惰。然后它将避免b
- 字符。如果您想要两个位置,请使用组来拆分匹配的值。您会发现每个组都有Index
。
[regex]$regex = "(a)(b*)"
$regex.Matches("ababab").Groups | ft Value, Index, Length -AutoSize
Value Index Length
----- ----- ------
ab 0 2
a 0 1
b 1 1
ab 2 2
a 2 1
b 3 1
ab 4 2
a 4 1
b 5 1
您也可以尝试使用不会消耗普通模式和嵌套组等字符的外观来捕获值。例如:
[regex]::Matches("aaaa", "(?=(aa?))").Groups | ? { $_.Value } | ft Value, Index, Length -AutoSize
Value Index Length
----- ----- ------
aa 0 2
aa 1 2
aa 2 2
a 3 1
#Making it lazy will return only the single a's
[regex]::Matches("aaaa", "(?=(aa??))").Groups | ? { $_.Value } | ft Value, Index, Length -AutoSize
Value Index Length
----- ----- ------
a 0 1
a 1 1
a 2 1
a 3 1
#Using nested groups can capture both
[regex]::Matches("aaaa", "(?=((a)a?))").Groups | ? { $_.Value } | ft Value, Index, Length -AutoSize
Value Index Length
----- ----- ------
aa 0 2
a 0 1
aa 1 2
a 1 1
aa 2 2
a 2 1
a 3 1
a 3 1
#Removing duplicates (might be fixable in the regex too, but I'm tired)
[regex]::Matches("aaaa", "(?=((a)a?))").Groups | ? { $_.Value } | Select-Object -Property Value, Index, Length -Unique | Ft -AutoSize
Value Index Length
----- ----- ------
aa 0 2
a 0 1
aa 1 2
a 1 1
aa 2 2
a 2 1
a 3 1