正则表达式捕获重复模式的问题

3
假设我有以下字符串:
Some crap string here...(TRACK "title1" F (S #h88 (P #m6) (P #m31)) (S #k3 (P #m58) (P #m58)))(TRACK "title2" P (S #a54 (P #r8)) (S #v59 (P #a25) (P #y82)))...Some other crap string here 我需要从这个字符串中提取以下数据:
1. title1 2. F 3. (S #h88 (P #m6) (P #m31)) 和 (S #k3 (P #m58) (P #m58))

1. title2 2. P 3. (S #a54 (P #r8)) 和 (S #v59 (P #a25) (P #y82))
其中:
1. 是某种标题。 2. 是某种状态。 3. 是某种列表,如 (S #xx (P #xx))。
由于我的正则表达式知识有限,我可以获取1和2,但只能获取3的第一部分。
(S #xx (P #xx))可以存在多次,内部的(P #xx)也可以存在多次。
我尝试了许多正则表达式,并咨询了很多帖子,但我仍然无法按要求提取数据。
所以现在我回到了\(TRACK "(.*?)" ([P|F]) (\(S.*?\)\)),它只捕获此示例字符串中两个列表中的第一个。
请参见:https://regex101.com/r/FM0ZZR/1 我需要做什么才能获取所有描述的列表?
1个回答

2

您可以使用

\(TRACK\s+"([^"]*)"\s+([PF])((?:\s+(\([SP](?:[^()]*+|(?-1))*\)))*\))

请查看正则表达式演示

细节

  • \(TRACK - 匹配 (TRACK 子字符串
  • \s+ - 一个或多个空格字符
  • " - 一个双引号字符
  • ([^"]*) - 第一组: 除双引号字符外的任意零个或多个字符
  • " - 一个双引号字符
  • \s+ - 一个或多个空格字符
  • ([PF]) - 第二组: PF
  • ((?:\s+(\([SP](?:[^()]*+|(?-1))*\)))*\)) - 第三组:
    • (?:\s+(\([SP](?:[^()]*+|(?-1))*\)))* - 零个或多个重复的
      • \s+ - 一个或多个空格字符
      • (\([SP](?:[^()]*+|(?-1))*\)) - 第四组 (技术性的,递归必需):
        • \( - 一个左圆括号字符
        • [SP] - SP
        • (?:[^()]*+|(?-1))* - 零个或多个除左圆括号和右圆括号字符外的字符,或最近捕获的整个模式
        • \) - 一个右圆括号字符
    • \) - 一个右圆括号字符。

非常感谢,但不幸的是,这个正则表达式没有捕获每个匹配的第一个(S #xx (P #xx))。例如:(S #h88 (P #m6) (P #m31))。 - DigiLive
1
@DigiLive 它确实捕获了它,但由于它是一个重复捕获组,只有最后一个值被保留在组内存缓冲区中。您无法使用PCRE模式访问每个单独的捕获,因为它不支持捕获组堆栈。您可以像这样编写它:(?:\G(?!\A)|\(TRACK\s+"([^"]*)"\s+([PF]))\s+(\([SP](?:[^()]*+|(?-1))*\))\)?,但它将不太可用,或需要相当多的额外代码。 - Wiktor Stribiżew
使用 (?-1) 对子模式进行递归很酷,这些模式太棒了 ++ - The fourth bird

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接