繁体   English   中英

RegEx:匹配引号中字符集的第二次出现

[英]RegEx: Match second occurrence of character set in in quotes

我希望匹配用引号括起来的字符集的第二次出现。 例如:

"{08165EA0-E946-11CF-9C87-00AA005127ED}"="WebCheckWebCrawler"

我只想选择WebCheckWebCrawler ,而不是08165EA0-E946-11CF-9C87-00AA005127ED

这是我到目前为止所拥有的,但我无法选择第二次出现。

https://regex101.com/r/Dr7ly2/4

谢谢你的帮助。

通用解决方案

在大多数情况下,通过从字符串中提取所有多个匹配项,然后通过其索引获取必要的项来获取第 n 次匹配项。 只是 Powershell 中的一个快速示例:

Select-String '"([^"]+)"' -input $str -AllMatches | % { $_.matches } |
    % { $_.groups[1].value } | select -Skip 1 -First 1

这里, Select-String '"([^"]+)"' -input $str -AllMatches | % { $_.matches } | % { $_.groups[1].value }获取所有匹配项并收集所有 Group 1 个值(双引号内的子串,不包括引号),然后select -Skip 1 -First 1省略第一项并获取下一项成为第一项。在其他语言中,也有类似的方法。但是,这需要一些代码并且被认为是“昂贵的”,因为应该为所有匹配项及其内部结构分配内存。

具体解决方案

在文本编辑器和没有允许获取多个正则表达式匹配项的正则表达式方法的语言中,上述解决方案不起作用。 在这些情况下,这种正则表达式用于获取第二个匹配项:

^(?:.*?"([^"]*)"){2}
^(?:[^"]*"([^"]*)"){2}
^(?:.*?(<YOUR_PATTERN_HERE>)){2}

请参阅正则表达式演示 注意:这需要一个正则表达式方法,该方法返回带有捕获的子字符串(子匹配、捕获)的整个匹配对象结构。 另外,请注意.*? 默认情况下不匹配换行符,并且比[^"]*慢,后者可以匹配换行符,并且速度更快。

详情

  • ^ - 字符串的开始
  • (?: - 一个非捕获组开始:
    • .*? - 尽可能少的除换行符以外的零个或多个字符
    • " - 一个"字符
    • ([^"]*) - 捕获组 1:除"之外的任何零个或多个 ( * ) 字符
    • " - 一个"字符
  • ){2} - 组结束,重复两次。

如果你想要整场比赛怎么办? 这取决于正则表达式库。 在 Powershell 中,很容易获得,因为 .NET 正则表达式支持无限宽度的后视模式:

(?<=^(?:[^"]*"[^"]*"){1}[^"]*")[^"]*(?=")

请参阅此正则表达式演示 请注意.*? 被替换为[^"]* ,以确保没有"可以在两者之间匹配"..."(?<=^(?:[^"]*"[^"]*")回顾后会匹配多这里有更多的字符串。

Powershell 代码片段:

Select-String '(?<=^(?:[^"]*"[^"]*"){1}[^"]*")[^"]*(?=")' -input $str | % { $_.matches.value }

在 PCRE 中,您可以使用

^(?:.*?"[^"]*"){1}.*?"\K[^"]*(?=")

请参阅正则表达式演示 \\K从整体内存匹配中省略了到目前为止匹配的整个文本,因此返回的只是与最后一个[^"]*匹配的文本部分( (?=")是正前瞻,其模式匹配不是添加到整体匹配中,因为这是一个非消耗模式)。 在 PHP、R、Sublime Text (PCRE)、Ruby (Onigmo)、Notepad++ (Boost) 中使用是很好的。 不幸的是,Powershell 不支持\\K

当前场景解决方案

您不需要使用如此复杂的模式。 您可以使用

="([^"]+)"

请参阅正则表达式演示

细节

  • =" - a ="子串
  • ([^"]+) - 组 1 捕获 1 个或多个字符而不是"
  • " -一个"

获取 Group 1 中的值$matches[1]

在Powershell中,你需要的值可以这样获取:

PS> $str = '"{08165EA0-E946-11CF-9C87-00AA005127ED}"="WebCheckWebCrawler"';
PS> $pattern = '="([^"]+)"'
PS> $str -match $pattern
True
PS> $matches[1]
WebCheckWebCrawler
PS>

尝试这个。

 let str = '"{08165EA0-E946-11CF-9C87-00AA005127ED}"="WebCheckWebCrawler"'; console.log(str.match(/(?<=\\=)".*?"/g));

要捕获,您可以使用:

="(.*)"

检查演示

你也可以使用: ="(.*?)"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM