在 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 Functioneval 安全一点,但我仍然必须防御任意代码执行攻击。

Never use 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);