2015-12-06 3 views
4

У меня есть строка, которая содержит булеву логику, то вдоль линий:Оценивать логическое выражение в строке в JavaScript, без Eval

((true && true) || false && !true) 

Что такое лучший способ в JavaScript, чтобы безопасно оценить эту строку, чтобы получить boolean result? Я бы хотел избежать использования eval().

+3

Если вы не хотите использовать 'Eval()' вам придется написать парсер для вашего выражения грамматики. – Pointy

+0

Вы можете использовать конструктор функций. 'Функция ('return' + expression)()' – jcubic

+2

@jcubic это правда, но кто-то, кто не хочет использовать 'eval()', вероятно, не хочет использовать что-то эквивалентно опасное. – Pointy

ответ

-1

Вы можете использовать услугу Angular $parse. Угловые выражения разбора, без eval их.

Пример использования:

var x=$parse(' ((true && true) || false && !true) ')() 
console.log(x) // will return true 

Readmore:

var a=angular.module('app',[]) 
 
a.run(function($parse){ 
 
    alert($parse('true || false || true || false')()) 
 
    })
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<body ng-app=app>

+0

Это приближается. Есть ли эквивалент этого для ReactJS? – dfj

1

Я написал эту булеву строку парсер другой вопрос:

var exp1 = "(true && true || false) && (true || (false && true))"; 
 
var exp2 = "((true && true) || false && !true)"; 
 
var exp3 = "(true && !false) && true && !false"; 
 
var exp4 = "(a && b) && c && d"; 
 

 
console.log(exp1 + ' = ' + parseBoolStr(exp1)); 
 
console.log(exp2 + ' = ' + parseBoolStr(exp2)); 
 
console.log(exp3 + ' = ' + parseBoolStr(exp3)); 
 
console.log(exp4 + ' = ' + parseBoolStr(exp4)); 
 

 
function parseBoolStr(str) { 
 
    var expressions = {}; 
 
    var expressionRegex = new RegExp("\\((?:(?:!*true)|(?:!*false)|(?:&&)|(?:\\|\\|)|\\s|(?:!*\\w+))+\\)"); 
 
    var expressionIndex = 0; 
 
    str = str.trim(); 
 
    while (str.match(expressionRegex)) { 
 
    var match = str.match(expressionRegex)[0]; 
 
    var expression = 'boolExpr' + expressionIndex; 
 
    str = str.replace(match, expression); 
 
    match = match.replace('(', '').replace(')', ''); 
 
    expressions[expression] = match; 
 
    expressionIndex++; 
 
    } 
 
    return evalBoolStr(str, expressions); 
 
} 
 

 
function evalBoolStr(str, expressions) { 
 
    var conditions = str.split(' '); 
 
    if (conditions.length > 0) { 
 
    var validity = toBoolean(conditions[0], expressions); 
 
    for (var i = 1; i + 1 < conditions.length; i += 2) { 
 
     var comparer = conditions[i]; 
 
     var value = toBoolean(conditions[i + 1], expressions); 
 
     switch (comparer) { 
 
     case '&&': 
 
      validity = validity && value; 
 
      break; 
 
     case '||': 
 
      validity = validity || value; 
 
      break; 
 
     } 
 
    } 
 
    return validity; 
 
    } 
 
    return 'Invalid input'; 
 
} 
 

 
function toBoolean(str, expressions) { 
 
    var inversed = 0; 
 
    while (str.indexOf('!') === 0) { 
 
    str = str.replace('!', ''); 
 
    inversed++; 
 
    } 
 
    var validity; 
 
    if (str.indexOf('boolExpr') === 0) { 
 
    validity = evalBoolStr(expressions[str], expressions); 
 
    } else if (str == 'true' || str == 'false') { 
 
    validity = str == 'true'; 
 
    } else { 
 
    validity = window[str](); 
 
    } 
 
    for (var i = 0; i < inversed; i++) { 
 
    validity = !validity; 
 
    } 
 
    return validity; 
 
} 
 

 
function a() { 
 
    return false; 
 
} 
 
function b() { 
 
    return true; 
 
} 
 
function c() { 
 
    return true; 
 
} 
 
function d() { 
 
    return false; 
 
}

Функции a, b, c и d могут и должны быть удалены. Просто пример.

Использование: parseBoolStr('((true && true) || false && !true)');

 Смежные вопросы

  • Нет связанных вопросов^_^