Java 是否可以评估字符串比较的布尔表达式?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19383953/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to evaluate a boolean expression for String comparions?
提问by Envin
I will have a String like
我会有一个像
('abc' != 'xyz' AND 'thy' = 'thy') OR ('ujy' = 'ujy')
The String will be able to have as many "AND" groups as it wants. There will not be any nested groups within the AND groups. All groups will ALWAYS be serparated by an OR.
String 将能够拥有任意数量的“AND”组。AND 组中不会有任何嵌套组。所有组将始终由 OR 分隔。
I can just switch out the AND for &&
and OR for ||
.
我可以将 AND for&&
和 OR for切换出来||
。
What I would like is to pass this String into some type of eval method and output TRUE or FALSE.
我想要的是将此字符串传递给某种类型的 eval 方法并输出 TRUE 或 FALSE。
Is there anything out there that can do this?
有什么东西可以做到这一点吗?
采纳答案by Cirou
You can use the built-in Javascript engine coming with the JDK1.6 to evaluate string containing math expressions.
您可以使用 JDK1.6 附带的内置 Javascript 引擎来计算包含数学表达式的字符串。
You an give a lookup here: ScriptEngine
你可以在这里查找:ScriptEngine
Here an example:
这里有一个例子:
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();
}
}
}
Just remember to replace the following:
请记住替换以下内容:
'AND' with '&&',
'OR' with '||',
'=' must be '=='
'AND' 与 '&&',
'OR' 与 '||',
'=' 必须是 '=='
Otherwise it will not accept your expression and will throws a javax.script.ScriptException
否则它不会接受你的表达并抛出一个 javax.script.ScriptException
回答by Jans
you can use script
package to achieve this like
你可以使用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();
}
回答by Alexander Bezrodniy
I think you can try groovy (if it's an option for you) with it's groovy.util.Eval, but first you should process your string and replace AND\OR with && and ||.
我认为您可以使用 groovy.util.Eval 尝试使用 groovy(如果它是您的选择),但首先您应该处理您的字符串并用 && 和 || 替换 AND\OR。
回答by Rafael T
I think you have to parse it and write custom classes for it like this
我认为你必须像这样解析它并为它编写自定义类
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;
}
not tested, but it may point you into the right direction
未经测试,但它可能会为您指明正确的方向