2

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

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

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

例如。给定数字 3 和字符串“偶数和 > 10 或奇数和 < 21”,这将评估为 TRUE

谢谢

米奇

4

2 回答 2

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

and这支持由and分隔的多个子句or,没有括号并且and总是首先被评估。每个子句可以是even, odd, 或与数字的比较,允许>, <, >=, 和<=比较。

它通过将整个规则与正则表达式模式进行比较来确保其语法有效且受支持。如果它通过了该测试,那么随后的字符串替换将成功地将其转换为针对变量硬编码的可执行表达式$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
于 2013-06-30T08:45:04.500 回答
0

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

if(($number % 2 == 0 && $number > 10 ) || ($number % 2 != 0 && $number < 21)){
//Then it is true!
}
于 2013-06-30T07:55:50.790 回答