首页 > 解决方案 > 用于匹配括号中所有内容的递归正则表达式 (PCRE)

问题描述

我很惊讶不能轻易找到类似问题的答案。我想匹配某些功能中的所有内容。这个想法是删除无用的功能。

foo(some (content)) --> some (content)

所以我试图匹配函数调用中可以包含括号的所有内容。这是我的 PCRE 正则表达式:

(?<name>\w+)\s*\(\K
(?<e>
     [^()]+
     |
     [^()]*
         \((?&e)\)
     [^()]*
)*
(?=\))

https://regex101.com/r/gfMAIM/1

不幸的是,它不起作用,我真的不明白为什么。

标签: regexpcre

解决方案


您的 Groupe模式没有做正确的工作,目前,它匹配具有 1 个深度级别的括号,因为您只递归了该e模式一次。它需要匹配尽可能多的(...)子字符串,因此,子例程模式需要在一个*+量化组内,甚至可以“简化”为(?<e>[^()]*(?:\((?&e)\)[^()]*)*).

请注意,您的 Groupe模式等于(?<e>[^()]+|\((?&e)\))*[^()]*around\((?&e)\)是多余的,因为替代方案将消耗当前深度级别[^()]+以外的字符()

此外,您量化了 Groupe模式,使其成为重复捕获组,仅在最后一次迭代期间保持文本匹配。

您可以使用

(?<name>\w+)\s*\(\K(?<e>[^()]*(?:\((?&e)\)[^()]*)*)(?=\))

查看正则表达式演示

细节

  • (?<name>\w+)\s*\(\K- 1+ 个单词字符,0+ 个空格,并且(从匹配中省略
  • (?<e>- 小组开始e
    • [^()]*- 0+ 字符除了()
    • (?:- 非捕获组的开始:
      • \(- 一个 (字符
      • (?&e)- 组e模式递归
      • \)- 一种)
      • [^()]*- 0+ 字符除了()
    • )*- 0 次或多次重复
  • )-e小组结束
  • (?=\))- a)必须紧邻当前位置。

推荐阅读