将String评估为条件Java

时间:2012-06-06 16:02:38

标签: java string parsing

我必须从D / B中检索一组列值并将其作为条件检查。

例如,我会在D / B列中添加"value > 2""4 < value < 6"等字符串。 (值是一直比较的值)。我将在我的代码中声明一个变量值,我应该评估这个条件。

int value = getValue();
if (value > 2)  //(the string retrieved from the D/B)
  doSomething();

我该怎么做?任何帮助都是很受欢迎的。感谢。

8 个答案:

答案 0 :(得分:32)

以下是使用标准(Java 1.6+)脚本库的示例:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class Test {

    public static void main(String[] args) throws Exception {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("JavaScript");

        engine.eval("value = 10");
        Boolean greaterThan5 = (Boolean) engine.eval("value > 5");
        Boolean lessThan5 = (Boolean) engine.eval("value < 5");

        System.out.println("10 > 5? " + greaterThan5); // true
        System.out.println("10 < 5? " + lessThan5); // false
    }
}

答案 1 :(得分:1)

这不会是微不足道的:您需要一个解析器来处理数据库中使用的表达式语言。如果它是一些标准的,指定良好的语言,那么你可能能够在互联网上找到一个,但如果它是内部的东西,那么你可能需要编写自己的(可能使用像ANTLR这样的解析器生成器。)< / p>

javax.script包中包含一些用于集成外部脚本引擎(如Javascript解释器)的工具。另一种想法是引入脚本引擎并将表达式提供给它。

答案 2 :(得分:1)

您基本上是在评估脚本表达式。根据表达式中允许的内容,您可以使用非常简单的东西(标识组的正则表达式)或非常复杂(嵌入javascript引擎?)。

我假设您正在查看简单的案例,其中表达式为:   [boundary0] [operator]“value”[operator] [boundary1]

可能省略[boundary] [operator]组中的一个,但不是两个。 (如果两者都是礼物,操作员应该是相同的)

我会使用正则表达式来捕获组。

类似于:(?:( \ d +)\ s *([&lt;&gt;])\ s *)?value(?:\ s *([&lt;&gt;])\ s *(\ d + ))?

然后:   boundary1 = group(1); operator1 = group(2); operator2 = group(3); boundary2 = group(4)

答案 3 :(得分:0)

最新版本的Java(Java 7)允许使用字符串上的Switch Case语句,如果没有太多可能的变体,您可以这样做或类似:

int value = getValue();
switch(myString) {
  case "value > 2" : if (value > 2) {  doSomething();} break;
  case "4 < value < 6" : if (value > 4 && value < 6) {  doSomethingElse();} break;
  default : doDefault();
}

答案 4 :(得分:0)

您应该尝试通过执行类似

的操作来解析if语句中的字符串
if(parseMyString(getValue()))
    doSomething();

在parseMyString中可以确定您需要为条件评估的内容。如果您不知道如何创建解析器,请查看:http://www.javapractices.com/topic/TopicAction.do?Id=87

答案 5 :(得分:0)

为了最大限度地灵活地评估条件,请使用专为嵌入而设计的脚本语言,例如MVEL可以解析和评估简单条件表达式,就像问题中那样。

使用MVEL比在Java 1.6+中使用Scripting引擎(特别是使用JavaScript)有一个巨大的优势:使用MVEL,您可以编译脚本到字节码,使他们的评估更加高效运行时。

答案 6 :(得分:0)

这本身并不回答你的问题;它提供了可能产生相同结果的替代解决方案。

不是使用定义条件的伪代码存储单个数据库列,而是创建一个表,其中模式定义必须满足的条件类型以及这些条件的值。这简化了对这些条件的编程评估,但如果您有各种类型的条件需要评估,它可能会变得复杂。

例如,您可能有一个如下所示的表。

CONDITION_ID | MINIMUM | MAXIMUM | IS_PRIME  |   ETC.
______________________________________________________
      1      |    2    |   NULL  |   NULL    |   ...
      2      |    4    |    6    |   NULL    |   ...

这些行条目分别映射到规则value > 26 > value > 4

与您提供的方法相比,这可以带来许多好处。

  • 提高性能和清洁度
  • 您的条件可以在数据库级别进行评估,并可用于过滤查询
  • 您无需担心处理伪代码语法被破坏的情况

答案 7 :(得分:-4)

除了使用Java 7之外,这样做的一个非常好的方法是使用枚举。 声明枚举如下所示

上面的枚举有一个常量集合,其值设置为您希望从数据库返回的字符串。由于您可以在交换机情况下使用枚举,因此剩下的代码变得简单

enum MyEnum
{
    val1("value < 4"),val2("4<value<6");
    private String value;

    private MyEnum(String value)
    {
        this.value = value;
    }
}


public static void chooseStrategy(MyEnum enumVal)
{   
    int value = getValue();
    switch(enumVal)
    {
        case val1:
        if(value > 2){}
        break;
        case val2:
        if(4 < value && value < 6) {}
        break;
        default:
    }
}

public static void main(String[] args)
{
    String str = "4<value<6";
    chooseStrategy(MyEnum.valueOf(str));
}

您所要做的就是将您的字符串传递给enum.valueof方法,它将返回适当的枚举,该枚举放在一个switch case块中以执行条件操作。在上面的代码中,您可以传递任何字符串来代替此示例中传递的内容