评估存储为字符串的多个条件

时间:2013-06-30 07:45:51

标签: php string evaluation

我在数据库中存储了一些字符串,其中包含必须满足的特定规则。规则是这样的:

>25
>25 and < 82
even and > 100
even and > 10 or odd and < 21

给定一个数字和一个字符串,在PHP中评估它的最佳方法是什么?

例如。给定数字3和字符串“even and&gt; 10 or odd和&lt; 21”,这将评估为TRUE

由于

米奇

2 个答案:

答案 0 :(得分:2)

正如评论中所提到的,解决方案可能非常简单或非常复杂。

我把一个函数放在一起,它将与你给出的例子一起使用:

function ruleToExpression($rule) {
    $pattern = '/^( +(and|or) +(even|odd|[<>]=? *[0-9]+))+$/';
    if (!preg_match($pattern, ' and ' . $rule)) {
        throw new Exception('Invalid expression');
    }
    $find = array('even', 'odd', 'and', 'or');
    $replace = array('%2==0', '%2==1', ') && ($x', ')) || (($x');
    return '(($x' . str_replace($find, $replace, $rule) . '))';
}

function evaluateExpr($expr, $val) {
    $x = $val;
    return eval("return ({$expr});");
}

这支持由andor分隔的多个子句,没有括号,and始终首先被评估。每个子句可以是evenodd或与数字进行比较,从而允许><>=<=比较。

它的工作原理是将整个规则与正则表达式模式进行比较,以确保其语法有效并受支持。如果它通过了该测试,那么后面的字符串替换将成功地将其转换为针对变量$x进行硬编码的可执行表达式。

举个例子:

ruleToExpression('>25');
// (($x>25))

ruleToExpression('>25 and < 82');
// (($x>25 ) && ($x < 82))

ruleToExpression('even and > 100');
// (($x%2==0 ) && ($x > 100))

ruleToExpression('even and > 10 or odd and < 21');
// (($x%2==0 ) && ($x > 10 )) || (($x %2==1 ) && ($x < 21))

evaluateExpr(ruleToExpression('even and >25'), 31);
// false

evaluateExpr(ruleToExpression('even and >25'), 32);
// true

evaluateExpr(ruleToExpression('even and > 10 or odd and < 21'), 3);
// true

答案 1 :(得分:0)

为什么不将字符串even翻译成数学?如果您使用mod,则可以像$number % 2 == 0一样编写它。在这种情况下,您的示例将是:

if(($number % 2 == 0 && $number > 10 ) || ($number % 2 != 0 && $number < 21)){
//Then it is true!
}