6

I have a string that contains Boolean logic something like:

var test = "(true)&&(false)&&!(true||true)"

What is a good way to evaluate this string in JavaScript to get the boolean value of false in this case

  1. I know we could use eval() or new Function().. - but is that a safe approach?
  2. I am guessing the other option would be to write a custom parser. Being a fairly new person to JS, would that be a lot of effort? I could not find any examples of parsers for Boolean logic expressions
  3. Any other alternatives?
12
  • 3
    What is the source of "(true)&&(false)&&!(true||true)" ? Commented Apr 1, 2016 at 5:08
  • I am parsing the response from the server and building that string based on some logic Commented Apr 1, 2016 at 5:12
  • You could use server returned data as bool after applying logic. Why do u convert it to string? Commented Apr 1, 2016 at 5:13
  • It's safe to use eval only when you can guarantee the source isn't malicious and doesn't contain an issue. If you're the one building the string and you've written your code to guarantee only a boolean string is constructed, it should be fine. Commented Apr 1, 2016 at 5:13
  • If the syntax was like "(1)&(0)&!(1||1)" (all tokens are only 1 character), it would be easier to parse Commented Apr 1, 2016 at 5:13

5 Answers 5

2

As long as you can guarantee it to be safe, I think you could use eval.

Maybe by treating it before doing an eval?

var test = "(true)&&(false)&&!(true||true)" 

var safe = test.replace(/true/ig, "1").replace(/false/ig, "0");

var match = safe.match(/[0-9&!|()]*/ig);

if(match) {
   var result = !!eval(match[0]);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Cannot be used if a Content Security Policy has disabled code evaluation though.
1

Javascript has a ternary operator you could use:

var i = result ? 1 : 0;

Here, result is Boolean value either True or False.

So, Your question will be something like that after this operation.

(1)&(0)&!(1||1)

I hope you can better evaluate now this Boolean logic.

Comments

1

you can use eval, Eg: eval("(true)&&(false)&&!(true||true)");

Comments

0

Try this code

function processExpression(expr)
{
  while (expr.indexOf("(" ) != -1 )
  {
    expr = expr.replace(/\([\w|]+\)/g, function(matched){ return processBrace(matched)});
  }
  return expr = processBrace( "(" + expr + ")" );
}
function processBrace(str)
{
    return str.substring(1).slice(0,-1).split(/(?=&|\|)/).map(function(value,index,arr){ 
        if ( index != 0 && index%2 == 0 ) { return arr[index-1] + value } else if(index==0){return value;} else {return ""}
    }).filter(function(val){return val.length > 0}).reduce(function(prev,current){
        var first = Boolean(prev);
        var operator = current.substring(0,2);
        var operand = current.substring(2); 
        while ( operand.indexOf("!") != -1 )
        {
           var boolval = operand.match(/\w+/)[0] == "false"; //flip the value by comparing it with false
           var negations = operand.match(/\W+/)[0];
           operand = negations.substring(1) + boolval;
        }
        var second = operand == "true";
        var output = operator == "&&" ? (first && second) : (first || second); 
        return output;
    });
}

DEMO

    function processExpression(expr)
    {
      while (expr.indexOf("(" ) != -1 )
      {
    	expr = expr.replace(/\([\w|]+\)/g, function(matched){ return processBrace(matched)});
      }
      return expr = processBrace( "(" + expr + ")" );
    }
    function processBrace(str)
    {
    	return str.substring(1).slice(0,-1).split(/(?=&|\|)/).map(function(value,index,arr){ 
    		if ( index != 0 && index%2 == 0 ) { return arr[index-1] + value } else if(index==0){return value;} else {return ""}
    	}).filter(function(val){return val.length > 0}).reduce(function(prev,current){
    		var first = Boolean(prev);
    		var operator = current.substring(0,2);
    		var operand = current.substring(2); 
    		while ( operand.indexOf("!") != -1 )
    		{
    		   var boolval = operand.match(/\w+/)[0] == "false"; //flip the value by comparing it with false
    		   var negations = operand.match(/\W+/)[0];
    		   operand = negations.substring(1) + boolval;
    		}
    		var second = operand == "true";
    		var output = operator == "&&" ? (first && second) : (first || second); 
    		return output;
    	});
    }


var example1 = "(true)&&(false)&&!(true||true)";
document.body.innerHTML += example1 + " -- " + processExpression(example1);

Comments

-2

Try using "".match() in ternary operator condition

"(true)&&(true)&&!(true||true)".match(/false/ig)?false:true

3 Comments

There's a ! Symbol i the statement
Thanks for your comment but downgrading the comment on your own thinking is not the right way, kindly i request you to be positive and don't downgrade my comment. Actually I don't write ! in my comment, I just copied it from the questioner. Thanks
With all due respect, the comment is downvoted because it's wrong. Your statement does not check if the condition given in the string is true or false, it only checks if the substring 'false' is present.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.