akoy
akoy

Reputation: 173

Evaluate string giving boolean expression in JavaScript

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?

Upvotes: 6

Views: 8991

Answers (5)

Muhammad Kamran
Muhammad Kamran

Reputation: 11

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

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

Upvotes: -2

gurvinder372
gurvinder372

Reputation: 68393

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

Upvotes: 0

Joseph
Joseph

Reputation: 692

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

Upvotes: 1

Rohìt Jíndal
Rohìt Jíndal

Reputation: 27202

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.

Upvotes: 1

loxxy
loxxy

Reputation: 13151

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]);
}

Upvotes: 2

Related Questions