繁体   English   中英

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

[英]Elegant way to do variable substitution in a java string

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

我有一个公式以“ 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字符串中的一组标记?

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

然后,分别对每个操作数进行替换。

最后,使用Operators将它们放回原处。

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

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

一个简单的方法是

String foumula = "A+B".replaceAll("\\bA\\b", readableA)
                      .replaceAll("\\bB\\b", readableB);

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

这样您便有了后来的操作数节点和运算符节点。
稍后,将遍历树并考虑数学优先级规则来评估此表达式。

我建议阅读有关表达式解析的更多信息。

仅匹配

如果您不必在进行替换后评估表达式,则可以使用正则表达式。 类似于(\\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或...)来解析表达式,或者找到可作为开源使用的代数表达式解析器并使用它。 (您必须在网上搜索以找到那些,我没有用过,但怀疑它们存在。)

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM