【问题标题】:How do I capture the 2nd match for each line?如何捕获每行的第二场比赛?
【发布时间】:2019-08-19 20:50:08
【问题描述】:

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

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

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

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

这是我的 PowerShell 代码:

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

例如:

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

我的代码所做的是得到

证书::CurrentUserRoot 证书::CurrentUserRoot

但我真正需要的是获得第二场比赛的字符串 \ ___\,即:

根 根

【问题讨论】:

    标签: regex powershell syntax-highlighting


    【解决方案1】:

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

    使用捕获组来匹配后面的内容;

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

    关于模式

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

    Regex demo | Try it online

    值在第一个捕获组中:

    $user = $matches[1]
    

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

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

    Regex demo | Try it online

    【讨论】:

    • 谢谢。这个实际上正在输出与我目前拥有的相同的东西。但是非常感谢你帮助我。
    • 您的值在第一个捕获组中(在 regex101demo 中以绿色突出显示)。它不需要字符数。
    • 啊,我看到了区别。但是,当我尝试将其与我的 powershell 脚本匹配时,它只会输出我的第一个捕获组。
    • @123testing123 你试过了吗$matches.Values[1]regular-expressions.info/powershell.html
    【解决方案2】:

    我猜,可能类似于,

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

    可能是一个选择。

    Demo 1

    或者只是,

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

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

    将简单地返回 Root 并且 40 是 [A-F0-9] 结束子字符串的长度。对于更灵活的量词,这个表达式可能会起作用:

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

    Demo 2

    【讨论】:

    • 演示 2 适合我。这就是我所需要的。但是 40 有什么用?
    • 是不是说如果超过40个字符或者少于40个字符就不行了?
    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2020-11-11
      • 2015-03-11
      • 1970-01-01
      • 2022-11-23
      • 1970-01-01
      • 1970-01-01
      • 2022-01-08
      • 1970-01-01
      • 2019-08-26
      相关资源
      最近更新 更多