如何捕获每行的第二场比赛?
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
该值在第一个捕获组中:
$user = $matches[1]
如果您希望匹配只使用您的脚本而不是第 1 组,您可以使用正后视来断言左边的内容是 2 次而不是 \
,然后是 \
(?<=^[^\\r\n]*\[^\\r\n]*\)[^\\r\n]+
使用 PowerShell 提供实用的替代方案:
PS> 'Microsoft.PowerShell.Security\Certificate::CurrentUser\Root\CDD4EEAE6000AC7F40C3802C171E30148030C072',
'Microsoft.PowerShell.Security\Certificate::CurrentUser\Root\BE36A4562FB2EE05DBB3D32323ADF445084ED656' |
ForEach-Object { ($_ -split '[::|\]')[4] }
Root
Root
以上通过分隔符 \
或 ::
对每个输入字符串进行标记,并提取第 4 个标记。
基本上,我需要每行匹配 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
该值在第一个捕获组中:
$user = $matches[1]
如果您希望匹配只使用您的脚本而不是第 1 组,您可以使用正后视来断言左边的内容是 2 次而不是 \
,然后是 \
(?<=^[^\\r\n]*\[^\\r\n]*\)[^\\r\n]+
使用 PowerShell
PS> 'Microsoft.PowerShell.Security\Certificate::CurrentUser\Root\CDD4EEAE6000AC7F40C3802C171E30148030C072',
'Microsoft.PowerShell.Security\Certificate::CurrentUser\Root\BE36A4562FB2EE05DBB3D32323ADF445084ED656' |
ForEach-Object { ($_ -split '[::|\]')[4] }
Root
Root
以上通过分隔符 \
或 ::
对每个输入字符串进行标记,并提取第 4 个标记。