【问题标题】:Parse math operations with PHP用 PHP 解析数学运算
【发布时间】:2011-04-27 11:56:24
【问题描述】:

我正在做一个项目,我需要创建一个函数来解析 4 个默认数学运算(加法、减法、乘法、除法)。如果该函数可以解析括号之间的操作,那就太好了。

所以,必须是函数首先检查乘法和除法运算(应该在解析括号之间的所有操作是否存在之后检查,并且该规则应该适用于括号运算[最大的问题是括号可以包含括号])。在做完所有的乘除运算之后,它应该做所有的加减运算。最终数字应由函数返回。

另一个不错的补充是一个正则表达式字符串,它将检查数学运算。

提前致谢!

【问题讨论】:

  • 对于你的括号问题:你应该学习递归来学习递归
  • “问题”以“我正在做一个项目”开头,但很快就变成了功能的愿望清单。
  • 对我来说听起来像是一个家庭作业问题。这是作业问题吗?
  • 也许数学解析器会帮助stackoverflow.com/questions/1015242/…
  • @Fivell:你为什么不把它作为答案提交?

标签: php regex


【解决方案1】:

这应该很安全:

function do_maths($expression) {
  eval('$o = ' . preg_replace('/[^0-9\+\-\*\/\(\)\.]/', '', $expression) . ';');
  return $o;
}

echo do_maths('1+1');

【讨论】:

  • 如果我也必须支持浮点数,我应该改变什么?/
【解决方案2】:

您可以使用eval()警告:确保输入的是数学运算,而不是其他任意输入或 php 代码)。

$input = "3 + (4 - 2 * 8) / 2";

eval('$result = ' . $input . ';');

echo "The result is $result";

【讨论】:

  • 我想知道如果您要检查任何无法识别的字符,是否有可能使 eval() 对数学表达式 100% 安全;即preg_replace('~[^0-9.()-+*/]~', '', $input);
  • @Martijn 可能会起作用,并且也是在接受的答案中使用的方法。
【解决方案3】:

【讨论】:

  • 仅链接回答
【解决方案4】:

我可以推荐https://github.com/andig/php-shunting-yard,它是 Shunting Yard 算法的 PSR-0 兼容实现。

【讨论】:

    【解决方案5】:

    正则表达式不是这里的答案;我建议使用expression tree,其中所有终端节点都是常量或变量,其余节点是运算符。例如,2 + 3 * 4 变为:

    + --- 2
      |
      --- * --- 3
            |
            --- 4
    

    然后,您使用depth-first traversal 计算表达式。在 PHP 中表示树有点困难,但您可以使用内置库作为评论者的建议,也可以使用数组的关联数组来表示它们。

    【讨论】:

      【解决方案6】:

      如果您想要一个真正安全的数学解析器,那么 eval 不会这样做。 bcParserPHP 可以做到。用PHP实现,不使用eval,非常安全。

      【讨论】: