需要 PHP 中的 Shunting Yard 实现,解释和解析字符串,执行数学比较并返回布尔结果
我正在寻找可以解释 php 中的字符串并执行简单数学计算的东西,然后返回一个布尔结果以确定表达式是 true 还是 false。
例如:
- Sue 输入“3*{mysalary}/9=10000”
- PHP 将其分成两个表达式 -explode('=',string);
- PHP 获取我的数据库字段列表,并用数据(类型转换为 int)替换任何“{}”分隔字段,
- 然后 PHP 计算数学表达式
- php,然后将生成的左侧与右侧
- 布尔结果进行比较。
听起来可能很复杂,但其实只需要非常简单即可。以下是限制条件: 1/ 数学运算符固定为:+ - / * 2/比较运算符固定为:=> < >= <= 3/不需要浮点比较,一切都可以在整数级别完成。因此,如果需要,任何除法都可以进行舍入,或者只是对最终结果进行舍入
。 永远只有两个表达式,带有一个比较运算符。 如果有任何错误,我们将返回 false。
有人已经看到可以做到这一点的东西了吗?我知道我可以做出一些东西,但为什么要重新发明轮子呢?
如果您还没有看到任何内容,您是否愿意列出一些您在构建此程序时可以想到的“陷阱”或警告。
阅读更多内容后,我意识到我可以使用调车场算法。有人用 PHP 实现过这个吗?
我知道 eval 可能是执行此操作的一种简单方法,但是,我担心用户可能很容易使用此方法破坏某些内容或导致语法错误。我宁愿不将其包含在解决方案中,或者如果我这样做,则需要严格控制它的使用方式。
谢谢。
贾森
I'm looking for something that can interpret a string in php and perform simple math calculation, and then return a boolean result as to whether the expression is true or false.
For example:
- Sue types in "3*{mysalary}/9=10000"
- PHP splits this up into two expressions - explode('=',string);
- PHP takes my list of database fields, and replaces any "{}" delimited fields with the data (typecasted to int)
- PHP then evaluates the maths expression
- php then compares the left side to the right side
- boolean result produced.
It may sound complex but it only needs to be very simple. Here are the constraints:
1/ mathematical operators are fixed to: + - / *
2/ comparison operators are fixed to: = > < >= <=
3/ do not need floating point comparisons, everything can be done at an integer level. So any divisions can be rounded if need be or simply just round the final result
There will only ever be two expressions, with one comparison operator.
If there is any sort of error at all we will just return false.
Has anyone seen something that can do this already? I know I can make something but why re-invent the wheel right?
If you haven't seen anything do you care to list some "gotcha's" or caveat's that you can think of when building this.
After reading some more I realise I could use the shunting yard algorithm. Does anyone have an implementation of this in PHP?
I am aware the eval could be an easy method to perform this, however, it concerns me that the user could very easily break something using this method or cause syntax errors. I'd rather not include it in the solution, or if i do then it'd need to tightly control how it is used.
Thanks.
Jason
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
查看 evalMath 类PHP 类。这几乎可以完成您想要的所有操作,包括变量替换(例如在计算表达式之前在示例中为“mysalary”设置一个值)
Take a look at the evalMath class on PHPClasses. This should do pretty much everything that you want, including variable substitution (such as setting a value for "mysalary" in your example before evaluating the expression)
有一个表达式解析器引擎(JavaScript+Node、PHP、Python和ActionScript的实现),在< a href="https://github.com/foo123/Xpresion" rel="nofollow">github Xpresion (ps.我是作者)
该引擎非常灵活且可配置,可以创建解析器解析任何还包含用户定义变量、用户定义函数、多态运算符和通用n元运算符的表达式strong>(例如三元 if-then-else)
该算法非常通用(可以说,是 调车场算法)
There is an expression parser engine (implementations for JavaScript+Node, PHP, Python and ActionScript), on github Xpresion (ps. i'm the author)
The engine is quite flexible and configurable, one can create parsers that parse any expression which also includes user-defined variables, user-defined functions, polymorphic operators and general n-ary operators (eg. ternary if-then-else)
The algorithm is quite general (one could say, a generalised variation of Shunting Yard algorithm)
我采取的方法是:
...
最难的一步是第二步;你必须考虑运算符优先级、括号和其他事情,但是有很多关于这方面的文献(你甚至可以点击维基百科链接)
The approach I'd take is:
Now...
The hardest step is the 2nd; you have to consider operator precedence, parentheses and other things, but there's plenty of literature on that (you can even just follow that wikipedia link)
为什么不简单地执行变量替换,然后执行
preg_replace("/[^0-9+-*\/]/", '', $inputString)
,然后使用eval()
还是create_function()
?如果你使用这个,你必须确保删除可能不安全的“语句”,这就是我使用 preg_replace 的原因,所以它会删除任何文字字符串
why dont you simply perform variables replacements, and then do a
preg_replace("/[^0-9+-*\/]/", '', $inputString)
, and then use eithereval()
orcreate_function()
?If you use this you MUST make sure that possibly unsafe "statements" are removed, that's why i used preg_replace, so it would remove any literal string