解析复杂的字符串表达式布尔在Javascript

Parse complex String Expression to Boolean in Javascript

本文关键字:布尔 Javascript 表达式 字符串 复杂      更新时间:2023-09-26

我已经得到了为复杂和嵌套json编写过滤器的任务。要做到这一点,我需要计算用户在输入字段中输入的布尔表达式。对于这个问题,假设我们有以下输入:

(Key1 = "foo" || key2 = 2 && key3 = "bar") && key4 = 7

我设法写了一个函数来评估每个键值对为"True"或"False",并在字符串中替换它们:例如:

(True || False && True) && True

现在我想把这个字符串解析成一个布尔表达式。是否有任何"简单"的方式(内置在函数,插件)的Javascript,可以解析这个字符串?

通常不建议使用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/。

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表达式字符串,并将其提供给var f = new Function('input', 'return ' + expression + ';'),在1KByte的压缩包中做类似的工作。new Functioneval更安全一点,但我仍然必须防御任意代码执行攻击。

为了避免使用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

永远不要使用eval()!

我还为我的项目写了一个小的表达式解析器。它缺少一些操作符和功能,但非常有用,而且超轻(缩小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);

这似乎是一个完美的地方使用eval。但是,请通过对这个问题的回答来了解此解决方案的缺点。

  • eval参考@ w3schools