在 Javascript 中将复杂的字符串表达式解析为布尔值
Parse complex String Expression to Boolean in Javascript
我的任务是为复杂的嵌套 JSON 编写过滤器。为此,我需要评估用户在输入字段中输入的布尔表达式。
为了这个问题,假设我们有以下输入:
(Key1 = "foo" || key2 = 2 && key3 = "bar") && key4 = 7
我设法编写了一个函数来将每个键值对评估为 "True" 或 "False" 并将它们替换为字符串:
例如:
(True || False && True) && True
现在我想将此字符串解析为布尔表达式。 Javascript 是否有任何 "easy" 方法(内置函数、插件)可以解析此字符串?
似乎是使用 eval
的完美场所。但是,look through answers to this SO question 了解此解决方案的缺点。
通常不建议使用 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/ or http://jsep.from.so/.
为了避免使用 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
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);
这个美丽的成本:92KByte 缩小包大小
我启动了项目 logic_fn,通过将自定义逻辑表达式(使用 &、AND、- 等自定义运算符)转换为 javascript,在 1KByte 缩小包中完成类似的工作表达式字符串,并将其提供给 var f = new Function('input', 'return ' + expression + ';')
。 new Function
比 eval
安全一点,但我仍然必须防御任意代码执行攻击。
我还为我的项目编写了一个小型表达式解析器。它缺少一些运算符和功能,但非常有用,而且超轻(1.6k 缩小)
工作原理如下:
- 输入一个对象“subject”,以及一个逻辑表达式字符串
- 找到最深的嵌套括号组
- 查找运算符
- 处理组并替换顶级组中的输出
- 循环
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);
我的任务是为复杂的嵌套 JSON 编写过滤器。为此,我需要评估用户在输入字段中输入的布尔表达式。 为了这个问题,假设我们有以下输入:
(Key1 = "foo" || key2 = 2 && key3 = "bar") && key4 = 7
我设法编写了一个函数来将每个键值对评估为 "True" 或 "False" 并将它们替换为字符串: 例如:
(True || False && True) && True
现在我想将此字符串解析为布尔表达式。 Javascript 是否有任何 "easy" 方法(内置函数、插件)可以解析此字符串?
似乎是使用 eval
的完美场所。但是,look through answers to this SO question 了解此解决方案的缺点。
通常不建议使用 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/ or http://jsep.from.so/.
为了避免使用 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
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);
这个美丽的成本:92KByte 缩小包大小
我启动了项目 logic_fn,通过将自定义逻辑表达式(使用 &、AND、- 等自定义运算符)转换为 javascript,在 1KByte 缩小包中完成类似的工作表达式字符串,并将其提供给 var f = new Function('input', 'return ' + expression + ';')
。 new Function
比 eval
安全一点,但我仍然必须防御任意代码执行攻击。
我还为我的项目编写了一个小型表达式解析器。它缺少一些运算符和功能,但非常有用,而且超轻(1.6k 缩小)
工作原理如下:
- 输入一个对象“subject”,以及一个逻辑表达式字符串
- 找到最深的嵌套括号组
- 查找运算符
- 处理组并替换顶级组中的输出
- 循环
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);