将字符串评估为条件 Java
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10917878/
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
Evaluate String as a condition Java
提问by Venkateshwarrao Surabhi
I have to retrieve a set of column values from D/B and check it as a condition.
我必须从 D/B 中检索一组列值并将其作为条件进行检查。
For example, I will have strings like "value > 2"
, "4 < value < 6"
in a D/B column. (value is the one which is compared all the time). I will have a variable value declared in my code and I should evaluate this condition.
例如,我将在 D/B 列中包含类似"value > 2"
, 的字符串"4 < value < 6"
。(值是一直比较的那个)。我将在我的代码中声明一个变量值,我应该评估这个条件。
int value = getValue();
if (value > 2) //(the string retrieved from the D/B)
doSomething();
How can I do this?? Any help is muceh appreciated. Thanks.
我怎样才能做到这一点??任何帮助都非常感谢。谢谢。
回答by assylias
Here is an example using the standard (Java 1.6+) scripting library:
以下是使用标准 (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
}
}
回答by Ernest Friedman-Hill
It's not going to be trivial: you need a parser for the expression language used in your database. If it's some standard, well-specified language, then you might be able to find one on the Internet, but if it's an in-house thing, then you may need to write your own (perhaps using a parser generator like ANTLR.)
这不会是微不足道的:您需要一个解析器来解析数据库中使用的表达式语言。如果它是某种标准的、明确指定的语言,那么您可能可以在 Internet 上找到一种语言,但如果它是内部的东西,那么您可能需要编写自己的语言(也许使用像 ANTLR 这样的解析器生成器。)
The javax.scriptpackage contains some tools for integrating external scripting engines like a Javascript interpreter. An alternative idea would be to bring in a scripting engine and feed the expressions to that.
该的javax.script包中包含用于集成外部脚本引擎,如JavaScript解释一些工具。另一种想法是引入脚本引擎并将表达式提供给它。
回答by ptyx
You are basically evaluating a scripted expression. Depending what is allowed in that expression, you can get away with something very simple (regular expression identifying the groups) or very complex (embed a javascript engine?).
您基本上是在评估脚本表达式。根据该表达式中允许的内容,您可以使用非常简单的(标识组的正则表达式)或非常复杂的(嵌入 javascript 引擎?)。
I'm assuming you're looking at the simple case, where the expression is: [boundary0] [operator] "value" [operator] [boundary1]
我假设您正在查看简单的情况,其中表达式为: [boundary0] [operator] "value" [operator] [boundary1]
Where one, but not both of the [boundary] [operator] groups might be omitted. (And if both are presents, operator should be the same)
可以省略一个,但不是两个 [边界] [运算符] 组。(如果两者都存在,操作员应该是相同的)
I would use a regular expression for that with capturing groups.
我会使用正则表达式来捕获组。
Something like: (?:(\d+)\s*([<>])\s*)?value(?:\s*([<>])\s*(\d+))?
类似于: (?:(\d+)\s*([<>])\s*)?value(?:\s*([<>])\s*(\d+))?
And then: boundary1 = group(1); operator1 = group(2); operator2 = group(3); boundary2 = group(4)
然后:boundary1 = group(1); 操作员 1 = 组(2);操作员 2 = 组(3);边界 2 = 组 (4)
回答by NimChimpsky
The latest version of java (Java 7) allows Switch Case statements on Strings, if there are not many possible variations you could just do this or similar :
最新版本的 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();
}
回答by AGE
You should try parsing the string inside the if statement by doing something like
您应该尝试通过执行以下操作来解析 if 语句中的字符串
if(parseMyString(getValue()))
doSomething();
In parseMyString can determine what you need to evaluate for the condition. If you don't know how to create a parser then take a look at: http://www.javapractices.com/topic/TopicAction.do?Id=87
在 parseMyString 中可以确定您需要为条件评估什么。如果您不知道如何创建解析器,请查看:http: //www.javapractices.com/topic/TopicAction.do?Id=87
回答by óscar López
For evaluating the conditions with maximum flexibility use a scripting language designed for embedding, for instance MVELcan parse and evaluate simple conditional expression like the ones in the question.
为了以最大的灵活性评估条件,请使用专为嵌入设计的脚本语言,例如MVEL可以解析和评估简单的条件表达式,如问题中的那些。
Using MVEL has one huge advantage over using the Scripting engine in Java 1.6+ (in particular, with JavaScript): with MVEL you can compilethe scripts to bytecode, making their evaluation much more efficient at runtime.
与在 Java 1.6+ 中使用脚本引擎相比,使用 MVEL 有一个巨大的优势(特别是使用 JavaScript):使用 MVEL,您可以将脚本编译为字节码,从而使它们在运行时的评估效率更高。
回答by cheeken
This doesn't answer your question per se; it offers an alternate solution that may effect the same result.
这本身并不能回答您的问题;它提供了可能会产生相同结果的替代解决方案。
Instead of storing a single database column with pseudocode that defines a condition, make a table in which the schema define types of conditions that must be satisifed and the values of those conditions. This simplifies programmatic evaluation of those conditions, but it may become complicated if you have a variety of types of conditions to evaluate.
不是使用定义条件的伪代码存储单个数据库列,而是创建一个表,其中模式定义必须满足的条件类型以及这些条件的值。这简化了对这些条件的程序化评估,但如果您要评估多种类型的条件,则可能会变得复杂。
For example, you might have a table that looks like the following.
例如,您可能有一个如下所示的表。
CONDITION_ID | MINIMUM | MAXIMUM | IS_PRIME | ETC.
______________________________________________________
1 | 2 | NULL | NULL | ...
2 | 4 | 6 | NULL | ...
Those row entries, respectively map to the rules value > 2
and 6 > value > 4
.
这些行条目分别映射到规则value > 2
和6 > value > 4
。
This confers a number of benefits over the approach you provide.
与您提供的方法相比,这带来了许多好处。
- Improved performance and cleanliness
- Your conditions can be evaluated at the database level, and can be used to filter queries
- You needn't worry about handling scenarios in which your pseudocode syntax is broken
- 提高性能和清洁度
- 您的条件可以在数据库级别进行评估,并可用于过滤查询
- 您无需担心处理伪代码语法被破坏的场景
回答by prashant
A very good way of doing this apart from using Java 7 is using enums. Declare enum as shown below
除了使用 Java 7 之外,一个很好的方法是使用枚举。如下所示声明枚举
The above enum has a collection of constants whose values are set to the strings that you expect would be returned from the database. As you can use enums in switch cases the remaining code becomes easy
上面的枚举有一组常量,其值设置为您期望从数据库返回的字符串。由于您可以在 switch case 中使用枚举,剩下的代码就变得简单了
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));
}
All you have to do is pass your string to the enum.valueof method and it will return the appropiate enum which is put in a switch case block to perform conditional operation . In the above code you can pass any string in place of what is passed in this example
您所要做的就是将您的字符串传递给 enum.valueof 方法,它会返回适当的枚举,该枚举放置在 switch case 块中以执行条件操作。在上面的代码中,您可以传递任何字符串来代替本示例中传递的内容