考虑字符串
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]*\)
返回cos(t(2)))+t(51)
,这当然不是理想的结果。
有关如何使用正则表达式实现此目的的任何想法?我特别坚持这个"相同数量的开括号和右括号"。
答案 0 :(得分:4)
Niels,这是一个有趣且棘手的问题,因为你正在寻找重叠的比赛。即使使用递归,任务也不是微不足道的。
你问过any idea how to achieve this with regex
,所以听起来即使matlab中没有这个,你会有兴趣看到一个答案,告诉你如何在正则表达式中做到这一点。
这对我来说很有意义,因为工具通常会更改他们使用的正则表达式库。例如,Notepad ++,曾经有瘫痪的正则表达式,在版本6中切换到PCRE。(碰巧,PCRE可以使用这个解决方案。)
在Perl和PCRE中,您可以使用这个简短的正则表达式:
(?=(\b\w+\((?:\d+|(?1))\)))
这将匹配:
cos(t(2))
t(2)
t(51)
例如,在php中,您可以使用此代码(请参阅online demo底部的结果)。
$regex = "~(?=(\b\w+\((?:\d+|(?1))\)))~";
$string = "cos(t(2))+t(51)";
$count = preg_match_all($regex,$string,$matches);
print_r($matches[1]);
它是如何运作的?
cos(t(2))
后,引擎会在cos(t(2))
之后,o
之前cos
cos(t(2))
,而只是将其捕获到组1.它匹配的是at this position in the string, looking ahead, we can see x
的断言。匹配此断言后,它会尝试从字符串中的下一个位置开始再次匹配它。(\b\w+\((?:\d+|(?1))\))
中,在\d+
之后,交替{ {1}}允许我们用|
重复第一个子程序,也就是说,我们当前所在的整个表达式。因此,我们不会递归整个正则表达式(包括一个前瞻),而是一个子表达式。