Parse complex String Expression to Boolean in Javascript
There's eval()
which is usually not recommended to use but maybe in your case it's suitable. See for more details: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
You could write:
eval("(true || false && true) && true") // Returns: 1
Note, that I had to rewrite True
to true
because True
is not a recognised as a boolean expression.
However, scopes are applied to eval()
so I could also write:
var True = 1;
var False = 0;
eval("(True || False && True) && True"); // Returns: 1
This could work for you if you know the variables in advance I guess. Otherwise, maybe have a look at https://silentmatt.com/javascript-expression-evaluator/ or http://jsep.from.so/.
https://github.com/joewalnes/filtrex
A simple, safe, JavaScript Filter Expression compiler for end-users
// 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);
the cost of this beauty: 92KByte minified bundle size
i started the project logic_fn, to do a similar job in a 1KByte minified bundle, by translating a custom logic expression (with custom operators like &, AND, -) to a javascript expression string, and feeding that to var f = new Function('input', 'return ' + expression + ';')
. new Function
is a bit more secure than eval
, but i still must defend against arbitrary code execution attacks.
To avoid using eval, I used http://jsep.from.so/ and then wrote a function to evaluate the output from 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
Never use eval()!
I also wrote a small expression parser for my projects. It's missing a few operators and features but is pretty useful, and super light (1.6k minified)
Here's how it works :
- input an object "subject", and a logical expression string
- find deepest nested parentheses group
- find operators
- process group and replace output in top level group
- loop
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);