【发布时间】:2013-01-15 22:19:10
【问题描述】:
我正在用 C# 创建一个科学计算器,并且我有一组线性函数,用户可以向其中添加条目。我需要预先解析一个数学表达式来检查这些函数以及其他数学函数的使用情况,跟踪函数的名称和(...) 中的内容,并用它们的评估结果替换它们。
以这个表达式为例:
Ans1+(x*2)-(y^3)+abs(z)-avg(x, 5, Ans2)-my2ndFunc(y - (x * 2))
我写了我自己的正则表达式,我需要在等式中匹配这些:
abs(z)
avg(x, 5, Ans2)
my2ndFunc(y - (x * 2))
我使用Regex Tester v1.5.3 对其进行了测试,但它根本不匹配任何项目。这是我使用的正则表达式:
\b([a-z][a-z0-9]*)\((..*)\)\b
什么正则表达式会匹配这些函数并存储函数名和参数内容?此外,如果有人提供有关如何进行匹配和获取捕获组内容的示例代码,那会很酷,但这不是必需的。
编辑 我不需要实际的数学解析器,我有实现调车场算法的muParser。我只需要做一个简单的搜索和替换,数学解析器负责实际的数学运算,我只需要正则表达式来查找要评估的部分。
我只需要一个简单的正则表达式来匹配: myfuncname(any content here)
【问题讨论】:
-
虽然可能(尽管不寻常、困难且不可移植)使用正则表达式在 C# 中执行此操作,但我建议不要这样做而是使用一个简单的解析器。这是因为数学表达式并不总是符合常规语言。例如,如果一个函数作为输入嵌套到另一个函数中怎么办?这来自最近用 C# 编写了一个科学计算器应用程序的人。相信我。使用解析器,将使其非常易于维护。
-
@TylerCrompton 我以前做过这个,我使用 muParser 引擎来处理数学方程解析并在一个类中编写我的函数处理它。对于嵌套函数,我只是使预解析函数递归。但是我不再有它的项目文件,而且我忘记了我使用的正则表达式。
-
当你有像 abs(avg(x, 5, Ans2)) 这样的嵌套时会发生什么?
-
@Rich 我使预解析函数递归。原始的正则表达式匹配并不关心函数括号内的内容,但在匹配后,它会检查函数括号内的捕获组,看它是否是嵌套在函数内的函数,如果是的话将该字符串传递给对其进行评估的预解析函数,将结果返回给顶级函数,然后用其结果替换函数调用,然后评估顶级函数。我以前做过,只是不记得匹配的正则表达式:
myfunc(any content here)