具有替代项的正则表达式捕获组不匹配

Regex Capturing Group with alternative doesn't match

我有以下字符串,我想在其中匹配有效的 <key>:<value> 对。

有效的 <key> 是任何带有非空白字符后跟 :
的内容 有效的 <value> 要么包含在 [] 中,要么包含在没有空格的字符串中。

key1:value1 key#2:@value#2 nyet key3:[@value#3, value4] key4:[value5] :bar

基本上我想匹配除 nyet:bar

之外的所有内容

我想出了以下正则表达式 \S+:(\S+|\[[^]]+\]),但它似乎与 key3:[@value#3, value4] 中的表达式不匹配。在捕获组中,第二个选择\[[^]]+\]应该匹配这个表达式,所以我不明白为什么它不匹配。

以下正则表达式有效:\S+:([^([ )]+|\[[^\]]+\])但感觉不够优雅。

问题:

  1. 为什么第一个正则表达式 \S+:(\S+|\[[^]]+\]) 不起作用?
  2. 更优雅的解决方案如何匹配键值对?

在模式中你可以 switch the alternatives \S+:(\[[^]]+\]|\S+) 但在那种情况下它也会匹配 []

您还可以 exclude 使用否定字符 class.

匹配第一部分 [^\s:]+:(\[[^]]+]|\S+) 中的 :

对于组,您可以使用交替并检查是否存在第 2 组或第 3 组的值。

([^\s:]+):(?:\[([^][]+)]|(\S+))

模式匹配:

  • ([^\s:]+) 捕获 组 1,匹配除空白字符或 :
  • 之外的任何字符
  • :匹配:
  • (?:非捕获组
    • \[([^][]+)] 匹配 [ 组 2 中捕获除 [] 之外的任何字符并匹配结束 ]
    • |
    • (\S+)组 3
    • 中捕获 1+ 个非空白字符
  • )关闭非捕获组

Regex demo


如果支持 conditional,您可以检查第 2 组是否捕获了 [。如果是这样,您可以捕获除第 3 组中括号之外的任何字符。

然后您需要的值在第 1 组和第 3 组中。

([^\s:]+):(?:(\[)(?=[^][]*]))?((?(2)[^][]+|\S+))\]?

Regex demo

  1. 您的正则表达式很接近。它失败了,因为 :\S 优先于 :\[
  2. 这个正则表达式有效:
/\S+:(?:\[[^\]]*\]|\S+)/g

解释:

  • \S+: - 1+ 个非space 字符和一个冒号
  • (?: - 非捕获组开始(用于 OR)
    • \[[^\]]*\] - [...] 模式
    • | - 逻辑或
    • \S+ - 1+ 个非space 字符
  • ) - 非捕获组结束