非常简单的问题,我的大脑今天被冻结,所以我想不出一个优雅的解决方案,我知道一个存在。
我有一个以“A + B”形式传递给我的公式
我还将公式变量映射到“可读名称”。
最后,我有一个公式解析器,它将计算公式的值,但前提是它以变量的可读名称传递。
例如,作为输入我得
String formula = "A+B"
String readableA = "foovar1"
String readableB = "foovar2"
我希望我的输出为“foovar1 + foovar2”
简单查找和替换的问题在于它很容易被破坏,因为我们无法保证“可读”名称是什么。让我们说我再次使用不同的参数
String formula = "A+B"
String readableA = "foovarBad1"
String readableB = "foovarAngry2"
如果我在一个循环中做一个简单的查找和替换,我将最终用我已经替换的可读名称替换大写A和B。
这看起来像是一个近似的解决方案,但我的变量没有括号
答案 0 :(得分:3)
您提供的链接是一个很好的来源,因为匹配使用模式是要走的路。这里的基本思想是首先使用匹配器获取令牌。在此之后,您将拥有操作员和操作数
然后,在每个操作数上单独进行替换。
最后,使用操作员将它们重新组合在一起。
答案 1 :(得分:0)
一个有点乏味的解决方案是扫描A和B的所有出现并在字符串中记下它们的索引,然后使用StringBuilder.replace(int start,int end,String str)方法。 (以幼稚的形式,这不会非常有效,接近方形复杂度,或更确切地说是“变量数量”*“可能替换的数量”)
如果您了解所有操作符,可以对它们进行拆分(如“+”),然后替换单个“A”和“B”(您必须先修改空白字符)当然)在数组或ArrayList中。
答案 2 :(得分:0)
一种简单的方法是
String foumula = "A+B".replaceAll("\\bA\\b", readableA)
.replaceAll("\\bB\\b", readableB);
答案 3 :(得分:0)
你的方法不能很好地工作
应将公式(数学表达式)解析为表达式结构(例如表达式树)。
这样您就拥有了以后的操作数节点和运营商节点。
之后,将遍历该表达式并遍历树并考虑数学优先级规则。
我建议您阅读更多关于表达式解析的内容。
答案 4 :(得分:0)
仅匹配
如果您在进行替换后不必评估表达式,则可以使用正则表达式。像(\b\p{Alpha}\p{Alnum}*\b)
或java字符串"(\\b\\p{Alpha}\\p{Alnum}*\\b)"
然后反复使用find()
查找所有变量并存储其位置。
最后,遍历这些位置并从旧位置构建一个新的字符串,并替换可变位。
不是它不会检查提供的表达式是否合理。例如,如果你给它)A 2 B(
并且只是替换A和B(如)XXX 2 XXX(
),它根本不介意。我不知道这是否重要。
这类似于您在问题中提供的链接,除非您需要与其使用的不同的正则表达式。您可以转到http://www.regexplanet.com/advanced/java/index.html播放正则表达式并找出可行的表达式。我用它建议的那个,它在A + B和A +(C * D)中找到它需要的就好了。
<强>解析强>
使用一个可用的解析器生成器(Antlr或Sable或...)解析表达式,或者找到一个可用作开源的代数表达式解析器并使用它。 (你必须搜索网络才能找到那些,我没有使用过,但怀疑它们存在。)
然后使用解析器生成表达式的解析形式,替换变量并使用新变量重构字符串形式。
这个可能会更好,但努力程度取决于您是否可以找到要使用的现有代码。
这还取决于您是否需要根据常规规则验证表达式是否有效。此方法最不可能接受无效表达式。