如何捕获每行的第二场比赛?

How do I capture the 2nd match for each line?

基本上,我需要每行匹配 1 个,但现在,我的正则表达式每行匹配 2 个。

https://regex101.com/r/KmgGwS/8

我的正则表达式正在寻找 2 个斜杠,它 returns 中间的字符串,但问题是我的路径有多个斜杠,我只需要将它与每行的第二个匹配项进行匹配

(?<=\).*?(?=\)

这是我的 PowerShell 代码:

if ( $_.PSPath -match ("(?<=::).*?(?=\)")) {
    $user = $matches.Values
}

例如:

Microsoft.PowerShell.Security\Certificate::CurrentUser\Root\CDD4EEAE6000AC7F40C3802C171E30148030C072
Microsoft.PowerShell.Security\Certificate::CurrentUser\Root\BE36A4562FB2EE05DBB3D32323ADF445084ED656

我的代码所做的就是获取

Certificate::CurrentUserRoot
Certificate::CurrentUserRoot

但我真正需要的是将字符串获取到第二个匹配项\___\,即:

Root
Root

我猜,可能是类似于

的表达
(?<=\)[^\]*(?=\[A-Z0-9]{40}$)

可能是一个值得研究的选项。

Demo 1

或者只是,

[^\]*(?=\[A-Z0-9]{40}$)

[^\]*(?=\[A-F0-9]{40}$)

只是 return Root 并且 40 是 [A-F0-9] 结束子字符串的长度。对于更灵活的量词,此表达式可能有效:

[^\]*(?=\[A-F0-9]*$)

Demo 2

您可以使用锚 ^ 来断言字符串的开头。重复 2 次匹配不是反斜杠或换行符后跟反斜杠。

使用捕获组匹配以下内容;

^[^\\r\n]*\[^\\r\n]*\([^\\r\n]+)

关于图案

  • ^ 字符串开头
  • [^\\r\n]*\[^\\r\n]*\ 匹配 2 次不是 \ 或者一个换行符,然后 \
  • ( 捕获组 1
    • [^\\r\n]+ 匹配 1+ 次不是 \ 或换行符
  • ) 关闭组 1

Regex demo | Try it online

该值在第一个捕获组中:

$user = $matches[1]

如果您希望匹配只使用您的脚本而不是第 1 组,您可以使用正后视来断言左边的内容是 2 次而不是 \,然后是 \

(?<=^[^\\r\n]*\[^\\r\n]*\)[^\\r\n]+

Regex demo | Try it online

使用 PowerShell 提供实用的替代方案:

PS> 'Microsoft.PowerShell.Security\Certificate::CurrentUser\Root\CDD4EEAE6000AC7F40C3802C171E30148030C072',
'Microsoft.PowerShell.Security\Certificate::CurrentUser\Root\BE36A4562FB2EE05DBB3D32323ADF445084ED656' |
  ForEach-Object { ($_  -split '[::|\]')[4] }

Root
Root

以上通过分隔符 \:: 对每个输入字符串进行标记,并提取第 4 个标记。