0

非常简单的问题,今天我的大脑被冻结了,所以我想不出一个我知道存在的优雅解决方案。

我有一个以“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。

这看起来像一个近似的解决方案,但我的变量周围没有括号

如何替换 Java 字符串中的一组标记?

4

5 回答 5

3

您提供的链接是一个很好的来源,因为使用模式匹配是要走的路。这里的基本思想是首先使用匹配器获取令牌。在此之后,您将拥有运算符和操作数

然后,在每个Operand上单独进行替换。

最后,使用Operators将它们重新组合在一起。

于 2013-01-16T18:24:16.607 回答
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 或 ...)解析表达式,或者找到可作为开源的代数表达式解析器并使用它。(您必须在网上搜索才能找到它们,我没有使用过,但怀疑它们存在。)

然后使用解析器生成表达式的解析形式,替换变量并用新变量重构字符串形式。

这个可能会更好,但工作量取决于您是否可以找到现有的代码来使用。

这还取决于您是否需要根据正常规则验证表达式是否有效。此方法很可能不会接受无效表达式。

于 2013-01-17T15:57:34.633 回答
0

一个简单的方法是

String foumula = "A+B".replaceAll("\\bA\\b", readableA)
                      .replaceAll("\\bB\\b", readableB);
于 2013-01-16T18:26:37.103 回答
0

您的方法不能正常工作,因为
应该将公式(数学表达式)解析为表达式结构(例如表达式树)。

这样您就有了后来的Operand Nodes 和Operator节点。
稍后将遍历树并考虑数学优先级规则来评估此表达式。

我建议阅读更多关于表达式解析的内容。

于 2013-01-16T18:28:01.993 回答
0
  1. 一个有点乏味的解决方案是扫描所有出现的 A 和 B 并记下它们在字符串中的索引,然后使用 StringBuilder.replace(int start, int end, String str) 方法。(在幼稚的形式下,这不是很有效,接近平方复杂度,或者更准确地说是“变量数”*“可能的替换数”)

  2. 如果您知道所有运算符,则可以对它们进行拆分(例如在“+”上),然后在数组中替换单个“A”和“B”(当然,您必须先修剪空白字符)或数组列表。

于 2013-01-16T18:25:11.550 回答