6

我会有一个像这样的字符串

('abc' != 'xyz' AND 'thy' = 'thy') OR ('ujy' = 'ujy')

字符串将能够拥有任意数量的“AND”组。AND 组中不会有任何嵌套组。所有组将始终由 OR 分隔。

我可以将 AND for&&和 OR for 换掉||

我想要的是将此字符串传递给某种类型的 eval 方法并输出 TRUE 或 FALSE。

有什么可以做到这一点吗?

4

4 回答 4

15

您可以使用JDK1.6 附带的内置Javascript 引擎来评估包含数学表达式的字符串。

您可以在这里查找:ScriptEngine

这里有一个例子:

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

public class Myclass {
    public static void main(String[] args) {

        try {

            ScriptEngineManager sem = new ScriptEngineManager();
            ScriptEngine se = sem.getEngineByName("JavaScript");
            String myExpression = "('abc' == 'xyz' && 'thy' == 'thy') || ('ujy' == 'ujy')";
            System.out.println(se.eval(myExpression));

        } catch (ScriptException e) {

            System.out.println("Invalid Expression");
            e.printStackTrace();

        }
    }
}

请记住替换以下内容:

'AND' 与 '&&',
'OR' 与 '||',
'=' 必须是 '=='

否则它不会接受你的表达并会抛出一个javax.script.ScriptException

于 2013-10-15T14:46:41.683 回答
2

你可以使用script包来实现这一点

    ScriptEngine engine = new ScriptEngineManager().getEngineByExtension("js");
    String[] vars = {"var1 = 'xyz'", "var2 = 'xyz'"};

    try {
        for (String var : vars) {
            engine.eval(var);
        }
        System.out.println(engine.eval("var1 == var2 "));
    } catch (ScriptException e) {
        e.printStackTrace();
    }
于 2013-10-15T14:48:33.517 回答
1

我认为您必须像这样解析它并为它编写自定义类

public interface StringEquals{

    public boolean equals(String s1, String s2);
}

public class Equals implements StringEquals{

    private String mS1;
    private STring mS2;

    public NotEquals(String s1, String s2){
        mS1 = s1;
        mS2 = s2;
    }


    public boolean equals(){
        return mSq1.equals(mS2);
    }
}

public class NotEquals implements StringEquals{

    private String mS1;
    private STring mS2;

    public NotEquals(String s1, String s2){
        mS1 = s1;
        mS2 = s2;
    }

    public boolean equals(){
        return !mS1.equals(mS2);
    }
}

public class AndGroup{

    private List<StringEquals> mStrings;

    public AndGroup(List<StringEquals> list){
        mStrings = list;
    }

    public boolean getResult(){
        for(StringEquals e: mStrings){
            if (!e.equals()){
                return false;
            }
        }
        return true;
    }



and a class to parse it:

public boolean eval(String evalString){
    List<AndGroup> groups = new LinkedList<AndGroup>();
    String[] ands = evalString.split("OR");
    for (String andExp : ands){
        List<StringEquals> list = new LinkedList<StringEquals>();
        String compares = andExp.split("AND");
        for (String comp: compares){
            if (comp.contains("!="){
                String[] notEqual = comp.split("!=");
                list.add(new NotEquals(notEqual[0], notEqual[1]));
            } else {
                 String[] equal = comp.split("=");
                 list.add(new Equals(equal[0], equal[1]);
            }
        }
        groups.add(new AndGroup(list));


    }
    for (AndGroup g: groups){
        if (g.getResult()){
            return true;
        }
    }
    return false;

}

未经测试,但它可能会为您指明正确的方向

于 2013-10-15T14:58:50.103 回答
0

我认为您可以使用 groovy.util.Eval 尝试 groovy(如果它是您的选择),但首先您应该处理您的字符串并将 AND\OR 替换为 && 和 ||。

于 2013-10-15T14:49:06.153 回答