我正在为其中包含的函数解析一种简单的语言(Excel 公式)。函数名称必须以任意字母开头,后跟任意数量的字母/数字,并以左括号结尾(中间没有空格)。例如 MyFunc(
。该函数可以包含任何参数,包括其他函数,并且必须以右括号 )
结尾。当然,括号内的数学是允许的 =MyFunc((1+1))
并且 (1+1)
不应被检测为函数,因为它使函数失败我刚才描述的规则。我的目标是识别公式中最高级别的函数调用,识别函数名称,提取参数。通过参数,我可以递归地查找其他函数调用。
使用这个tutorial我破解了以下正则表达式。似乎没有人能做到这一点。它们在下面粘贴的测试用例上都失败了。
这应该可以工作,但完全失败:
(?<name>[a-z][a-z0-9]*\()(?<body>(?>[a-z][a-z0-9]*\((?<DEPTH>)|\)(?<-DEPTH>)|.?)*(?(DEPTH)(?!)))\)
这适用于许多测试用例,但不适用于下面的测试用例。我认为它不能正确处理嵌套函数 - 它只是在嵌套中查找开括号/闭括号:
(?<name>[a-z][a-z0-9]*\()(?<body>(?>\((?<DEPTH>)|\)(?<-DEPTH>)|.?)*(?(DEPTH)(?!)))\)
这是打破所有这些的测试:
=Date(Year(A$5),Month(A$5),1)-(Weekday(Date(Year(A$5),Month(A$5),1))-1)+{0;1;2;3;4;5}*7+{1,2,3,4,5,6,7}-1
这应该匹配为:
Date(ARGUMENTS1)
Weekday(ARGUMENTS2)
Where ARGUMENTS2 = Date(Year(A$5),Month(A$5),1)
相反,它匹配:
ARGUMENTS2 = Date(Year(A$5),Month(A$5),1)-1)
我正在使用提供外部存储器的.net RegEx。
最佳答案
这完全在 .NET 正则表达式的能力范围内。这是一个工作演示:
using System;
using System.Text.RegularExpressions;
namespace Test
{
class Test
{
public static void Main()
{
Regex r = new Regex(@"
(?<name>[a-z][a-z0-9]*\()
(?<body>
(?>
\((?<DEPTH>)
|
\)(?<-DEPTH>)
|
[^()]+
)*
(?(DEPTH)(?!))
)
\)", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
string formula = @"=Date(Year(A$5),Month(A$5),1)-(Weekday(Date(Year((A$5+1)),Month(A$5),1))-1)+{0;1;2;3;4;5}*7+{1,2,3,4,5,6,7}-1";
foreach (Match m in r.Matches(formula))
{
Console.WriteLine("{0}\n", m.Value);
}
}
}
}
输出:
Date(Year(A$5),Month(A$5),1) Weekday(Date(Year((A$5+1)),Month(A$5),1))
The main problem with your regex was that you were including the function name as part of the recursive match--for example:
Name1(...Name2(...)...)
任何前面没有名称的左括号都不会被计算在内,因为它与最终的替代方案 |.?
匹配),并且这与右括号失去了平衡。这也意味着您无法匹配像 =MyFunc((1+1))
这样的公式,您在文本中提到但未包含在示例中。 (我添加了一组额外的括号来演示。)
编辑:这是支持不重要的带引号的括号的版本:
Regex r = new Regex(@"
(?<name>[a-z][a-z0-9]*\()
(?<body>
(?>
\((?<DEPTH>)
|
\)(?<-DEPTH>)
|
""[^""]+""
|
[^()""]+
)*
(?(DEPTH)(?!))
)
\)", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
关于.net - 正则表达式解析任意深度的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4029048/