我在数据库中存储了一些字符串,其中包含必须满足的特定规则。规则是这样的:
>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
由于
米奇
答案 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});");
}
这支持由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
答案 1 :(得分:0)
为什么不将字符串even
翻译成数学?如果您使用mod,则可以像$number % 2 == 0
一样编写它。在这种情况下,您的示例将是:
if(($number % 2 == 0 && $number > 10 ) || ($number % 2 != 0 && $number < 21)){
//Then it is true!
}