在java字符串中进行变量替换的优雅方法

时间:2013-01-16 18:20:39

标签: java parsing variables substitution formulas

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

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

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

How to replace a set of tokens in a Java String?

5 个答案:

答案 0 :(得分:3)

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

然后,在每个操作数上单独进行替换。

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

答案 1 :(得分:0)

  1. 一个有点乏味的解决方案是扫描A和B的所有出现并在字符串中记下它们的索引,然后使用StringBuilder.replace(int start,int end,String str)方法。 (以幼稚的形式,这不会非常有效,接近方形复杂度,或更确切地说是“变量数量”*“可能替换的数量”)

  2. 如果您了解所有操作符,可以对它们进行拆分(如“+”),然后替换单个“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或...)解析表达式,或者找到一个可用作开源的代数表达式解析器并使用它。 (你必须搜索网络才能找到那些,我没有使用过,但怀疑它们存在。)

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

这个可能会更好,但努力程度取决于您是否可以找到要使用的现有代码。

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