嵌套匹配的正则表达式

nie*_*els 2 regex recursion matlab nested

考虑字符串

cos(t(2))+t(51)

使用正则表达式,我想匹配cos(t(2)),t(2)t(51)。适合的一般模式是这样的

variable or function name + opening_parenthesis + contents + closing_parenthesis,

其中contents可以是具有相同数量左括号和右括号的任何表达式。

我正在使用[a-zA-Z]+\([\W\w]*\)which returns cos(t(2)))+t(51),这当然不是期望的结果。

关于如何使用正则表达式实现此目的有什么想法吗?我特别坚持这个“相同数量的左括号和右括号”。

zx8*_*x81 5

Niels,这是一个有趣且棘手的问题,因为您正在寻找重叠的匹配项。即使使用递归,任务也不是微不足道的。

您询问了any idea how to achieve this with regex,所以听起来即使这在 matlab 中不可用,您也会有兴趣看到一个向您展示如何在正则表达式中执行此操作的答案。

这对我来说很有意义,因为工具经常更改它们使用的正则表达式库。例如,Notepad++ 过去的正则表达式有问题,在版本 6 中切换到 PCRE。(碰巧,PCRE 可以使用此解决方案。)

在 Perl 和 PCRE 中,您可以使用这个简短的正则表达式:

(?=(\b\w+\((?:\d+|(?1))\)))
Run Code Online (Sandbox Code Playgroud)

这将匹配:

cos(t(2))
t(2)
t(51)
Run Code Online (Sandbox Code Playgroud)

例如,在 php 中,您可以使用此代码(请参阅在线演示底部的结果)。

$regex = "~(?=(\b\w+\((?:\d+|(?1))\)))~";
$string = "cos(t(2))+t(51)";
$count = preg_match_all($regex,$string,$matches);
print_r($matches[1]);
Run Code Online (Sandbox Code Playgroud)

它是如何工作的?

  1. 为了允许重叠匹配,我们使用前瞻。这样,在匹配之后cos(t(2)),引擎将把自己定位在in之前cos(t(2)),而不是之后。ocos
  2. 事实上,引擎实际上并不匹配cos(t(2)),而只是将其捕获到组 1。它匹配的是断言at this position in the string, looking ahead, we can see x。匹配此断言后,它会尝试从字符串中的下一个位置开始再次匹配它。
  3. 前瞻中的表达式(描述我们正在寻找的内容)几乎非常简单:在 中(\b\w+\((?:\d+|(?1))\)),在 之后\d+,交替|允许我们用 重复第一个子例程(?1),也就是说,我们当前所在的整个表达式。因此,我们不会递归整个正则表达式(其中包括前瞻),而是递归其子表达式。