如何使用正则表达式(递归?)匹配嵌套函数调用(括号对)?

4
我需要一个正则表达式(**)来匹配未知数量的嵌套函数。 所以
expression
function(expression)
function(function(expression))
function(function(function(expression)))
etc.

如果我添加一个多余的右括号作为结尾,那么正则表达式将无法匹配该括号。

(**) 请不要回答说通过解析(和计算括号数量)比使用正则表达式更容易 - 在思考一段时间后,我已经知道了!


1
这不是一种常规语言,因此不存在可以识别它的正则表达式。 - Fred Foo
3
使用解析(以及计数括号)比使用正则表达式更容易实现。 - hsz
4
@larsmans,你是正确的,正式的正则表达式无法表示这种情况,但确实有一些支持递归的正则表达式方言,例如PCRE或具有平衡组的.NET引擎。无论如何,这里应该使用适当的解析器,并且正则表达式仅用于标记化。 - Lucero
@SteveChambers:如果一个简单的基于堆栈的解析器可以解决这个问题,你能告诉我们为什么你想要一个正则表达式吗? - Fred Foo
@larsmans 感谢提问。这是使用JavaScript完成的,并且已经在正则表达式方面走得太远,无法更改。如果无法使用正则表达式(根据答案和否定的情况看是这样的),我将只能使用一个不太匹配所需内容的较差正则表达式... - Steve Chambers
3个回答

5

这不是递归的,但它可以解决问题。

前提条件:

  • 函数名称是字母数字/下划线,可能有前导空格。
  • 函数名称不以数字开头。
  • 表达式中没有括号。
  • 函数中仅嵌套一个表达式。

代码:

var target = "function(function(function(expression)))";
var pattern = /\s*([a-zA-Z_]\w*[(](\s*[a-zA-Z_]\w*[(]|[^()]+[)]|[)])+[)])/;
var matches = target.match(pattern);
var target= matches[1];

正则表达式剖析:

\s*             // 0+ white space characters
(               // Capture group for what you want
  [a-zA-Z_]     //   1 letter/underscore
  \w*           //   0+ word characters (alpha-numeric/underscore)
  [(]           //   left parenthesis
  (             //   PIECES:
    \s*         //     0+ white space characters
    [a-zA-Z_]   //     1 letter/underscore
    \w*         //     0+ word characters (alpha-numeric/underscore)
    [(]         //     left parenthesis
   |            //   OR
    [^()]+      //     1+ non-parenthesis characters
    [)]         //     right parenthesis
   |            //   OR
    [)]         //     right parenthesis
  )+            //   1+ of these PIECES
  [)]           //   right parenthesis
)

感谢您花时间阅读这篇文章。我特别喜欢您用于记录正则表达式的格式 - 这使得它非常清晰易懂。实际上,我已经完成了这个项目,并最终使用了类似于此的长正则表达式,可以处理三层嵌套。(如果您有兴趣,可以在此网页的源代码中查看:http://sic.azurewebsites.net)。由于Bart Kiers在被接受的答案中指出,Javascript不支持正则表达式中的递归匹配,因此被迫这样做。 - Steve Chambers
1
没问题,先生。虽然这不是一个递归正则表达式,但这难道不比“这是不可能的”更好的答案吗? - NoBrainer
我理解你的观点,但在你发帖之前已经有人回答了,并且我不愿意更改答案,因为Bart的答案确实回答了问题(“未知数量的嵌套函数”...“不可能”)。不过你的回答提供了一个有用的替代方案,所以感谢你。 - Steve Chambers
你要求一个正则表达式,可以获取未知数量嵌套函数内的参数。我给了你这个正则表达式,因此它是可行的,证明Bart是错误的。 - NoBrainer
可能出现了一些混淆。正则表达式应该匹配整个嵌套函数调用集合,直到最后一个适用的括号(如果存在更多括号,则不再匹配),而不是内部的表达式。 - Steve Chambers
我更新了它,包括整个嵌套函数调用集合。很好的发现。 - NoBrainer

5

我正在寻找一个正则表达式(**),它将匹配未知数量的嵌套函数。

一些正则表达式实现支持递归匹配(Perl、PHP、.NET),但JavaScript不支持。因此,你的问题的答案是:不,那是不可能的。


谢谢 - 我有点预料到这个结果(但还是希望能有解决方案)。 - Steve Chambers

0
值得注意的是,根据Bart Kiers的回答,一些正则表达式引擎(不包括JavaScript)具有扩展功能,可以提供递归匹配 - 但这样的功能不应被视为正则表达式的形式定义。

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