我有任务为复杂和嵌套的JSON编写过滤器。为此,我需要评估用户在输入字段中输入的布尔表达式。 为了问题,我们可以说有以下输入:
(Key1 = "foo" || key2 = 2 && key3 = "bar") && key4 = 7
我设法编写了一个函数,将每个keyValue-Pair评估为“True”或“False”,并将其替换为字符串: e.g:
(True || False && True) && True
现在我想将此String解析为布尔表达式。是否有任何“简单”的方法(内置函数,插件)可以解析这个字符串?
答案 0 :(得分:5)
通常不建议使用eval()
,但在您的情况下,它可能是合适的。有关详细信息,请参阅:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
你可以写:
eval("(true || false && true) && true") // Returns: 1
请注意,我必须将True
重写为true
,因为True
不是公认的布尔表达式。
但是,范围适用于eval()
所以我也可以写:
var True = 1;
var False = 0;
eval("(True || False && True) && True"); // Returns: 1
如果您事先知道变量,这可能对您有用。否则,请查看https://silentmatt.com/javascript-expression-evaluator/或http://jsep.from.so/。
答案 1 :(得分:0)
这似乎是使用eval
的完美场所。但是,look through answers to this SO question要了解此解决方案的缺点。
答案 2 :(得分:0)
为了避免使用eval,我使用了http://jsep.from.so/,然后编写了一个函数来评估jsep的输出:
function evaluateBooleanExpressionTree(tree) {
if (tree.type == "Literal") {
return tree.value;
}
else if (tree.type == "LogicalExpression") {
if (tree.operator == "&&") {
return evaluateBooleanExpressionTree(tree["left"]) && this.evaluateBooleanExpressionTree(tree["right"]);
}
else {
return evaluateBooleanExpressionTree(tree["left"]) || this.evaluateBooleanExpressionTree(tree["right"]);
}
}
else {
// Unexpected node parsed
return null;
}
}
evaluateBooleanExpressionTree(jsep("(true || false && true) && true"))
// true
答案 3 :(得分:0)
https://github.com/joewalnes/filtrex
面向最终用户的简单,安全的JavaScript过滤器表达式编译器
// Input from user (e.g. search filter)
var expression = '(key1 == "foo" || key2 == 2 && key3 == "bar") && key4 == 7';
// Compile expression to executable function
var myfilter = compileExpression(expression);
// Execute function
myfilter({Key1: "foo", key2: 2, key3: "bar", key4: 7}); // returns 1
myfilter({}); // returns 0
// filter an array of objects
var data = [{key1: "foo"}, {key1: "foo2"}];
var results = data.filter(myfilter);
这种美丽的代价:缩小捆绑包大小92KB
我启动了项目logic_fn,通过将自定义逻辑表达式(带有自定义运算符,例如&,AND,-)转换为javascript表达式字符串,并将其输入来完成1KB的最小捆绑包中的类似工作。到var f = new Function('input', 'return ' + expression + ';')
。 new Function
比eval
安全一些,但是我仍然必须防御任意代码执行攻击。
答案 4 :(得分:0)
我还为我的项目编写了一个小的表达式解析器。它缺少一些运算符和功能,但非常有用,而且超轻(1.6k 缩小)
这是它的工作原理:
https://github.com/nicopowa/operators
var myObject = {key1: "foo", key2: 2, key3: "bar", key4: 7};
var myExpression = "(key1 || key2 && key3) && key4";
var result = Operate.parse(myObject, myExpression);