【发布时间】:2016-02-12 21:15:27
【问题描述】:
我需要创建一个方法来接收包含数学表达式的字符串,并且必须:
- 先验证一下。
- 返回问题/问题(如果存在)(例如,类似这样的内容:
4+3+4/0或4+4+(((2-2*4)-)。 - 如果一切正常,解决它并返回最终值。
到目前为止我所做的是:
- 我知道
eval完全符合我的需要,但是它存在SQL 注入等问题。 - 我发现了正则表达式。
我真的不知道设计这种方法的最佳方式,以使其安全并使用括号、运算符和数字。我在想的是使用正则表达式来检查初始字符串是否等于匹配的字符串。如果是,我正在考虑使用eval 来计算最终值。您认为这是正确的做法吗?
不确定我应该做什么,我写道:
def math_eval(expression)
a = /\(* \s* \d+ \s* (( [-\+\*\/] \s* \d+ \)* \s* ) | ( [-\+\*\/] \s* \(* \s* \d+ \s* ))+/
puts "Let's Go"
puts a.match(expression)
end
math_eval("lets see if this works 1/ 2 * 3 hello world")
这是返回:
Let's Go
Empty string
我看过 Stack Overflow 的帖子
/\(* \s* \d+ \s* (( [-\+\*\/] \s* \d+ \)* \s* ) | ( [-\+\*\/] \s* \(* \s* \d+ \s* ))+/
将是正确的正则表达式过滤器。
我做错了什么?我应该改变我的方法吗?
编辑:我采用了不同的方法。您认为以下方法安全吗?
class FormulaCalculator
def formula_validator(string_formula)
extracted_formula = string_formula.tr('Ⓐⓐ⒜AaẠạÅåÄäẢảḀḁẤấẦầẨẩȂȃẪẫẬậẮắẰằẲẳẴẵẶặĀāĄąȀȁǺǻȦȧÁáǞǟǍǎÀàÃãǠǡÂâȺⱥÆæǢǣǼǽⱯꜲꜳꜸꜹꜺꜻⱭ℀⅍℁ªⒷⓑ⒝BbḂḃḄḅḆḇƁɃƀƂƃƄƅℬⒸⓒ⒞CcḈḉĆćĈĉĊċČčÇçƇƈȻȼℂ℃ƆꜾꜿℭ℅℆℄Ⓓⓓ⒟DdḊḋḌḍḎḏḐḑḒḓĎďƊƋƌƉĐđȡDZDzdzDŽDždžȸⅅⅆⒺⓔ⒠EeḔḕḖḗḘḙḚḛḜḝẸẹẺẻẾếẼẽỀềỂểỄễỆệĒēĔĕĖėĘęĚěÈèÉéÊêËëȄȅȨȩȆȇƎⱻɆɇƏǝℰⱸℯ℮ℇƐⒻⓕ⒡FfḞḟƑƒꜰℲⅎꟻℱ℻Ⓖⓖ⒢GgƓḠḡĜĝĞğĠġǤǥǦǧǴℊ⅁ǵĢģⒽⓗ⒣HhḢḣḤḥḦḧḨḩḪḫĤĥȞȟĦħⱧⱨꜦℍǶẖℏℎℋℌꜧⒾⓘ⒤IiḬḭḮḯIJijÍíÌìÎîÏïĨĩĪīĬĭĮįǏǐıƚỺⅈⅉℹℑℐⒿⓙ⒥JjĴĵɈɉȷⱼǰⓀⓚ⒦KkḰḱḲḳḴḵĶķƘƙꝀꝁꝂꝃꝄꝅǨǩⱩⱪĸⓁⓛ⒧LlḶḷḸḹḺḻḼḽĹĺĻļĽľĿŀŁłỈỉⱠⱡȽꝉꝈⱢLJLjljỊİịꞁ⅃⅂ȈȉȊȋℓℒⓂⓜ⒨MmḾḿṀṁṂṃꟿꟽⱮƜℳⓃⓝ⒩NnṄṅṆṇṈṉṊṋŃńŅņŇňǸǹÑñȠƞŊŋƝʼnNJNjnjȵℕ№Ⓞⓞ⒪OoÖöṎṏṌṍṐṑṒṓȪȫȬȭȮȯȰȱǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợƠơŌōŎŏŐőÒòÓóÔôÕõǑǒȌȍȎȏŒœØøǾǿꝊꝎꝏ⍥⍤ℴⓅⓟ⒫℗PpṔṕṖṗƤƥⱣℙǷꟼ℘Ⓠⓠ⒬QqɊɋℚ℺ȹⓇⓡ⒭RrŔŕŖŗŘřṘṙṚṛṜṝṞṟȐȑȒȓɌɍƦꝚꝛⱤ℞ℜℛ℟ℝⓈⓢ⒮SsṠṡṢṣṤṥṦṧṨṩŚśŜŝŞşŠšȘșȿꜱƧƨϨϩẞßẛẜẝ℠Ⓣⓣ⒯TtṪṫṬṭṮṯṰṱŢţŤťŦŧȚțȾⱦƬƮƫƭẗȶ℡™Ⓤⓤ⒰UuṲṳṴṵṶṷṸṹṺṻỦủỤụỨứỪừỬửỮữỰựŨũŪūŬŭŮůŰűǙǚǗǘǛǜŲųǓǔȔȕÛûȖȗÙùÚúÜüƯưɄƲƱⓋⓥ⒱VvṼṽṾṿɅ℣ỼⱱⱴⱽⓌⓦ⒲WwẀẁẂẃẄẅẆẇẈẉŴŵⱲⱳϢϣẘⓍⓧ⒳XxẊẋẌẍℵ×Ⓨⓨ⒴yYẎẏỾỿỲỳỴỵỶỷỸỹŶŷƳƴŸÿÝýɎɏȲȳƔẙ⅄ℽⓏⓩ⒵ZzẐẑẒẓẔẕŹźŻżŽžȤȥⱫⱬƵƶɀℨℤ', '')
if string_formula = extracted_formula
return true
else
return false
end
end
def formula_evaluation(string_formula)
if formula_validator(string_formula) == true
return eval(string_formula)
end
rescue Exception => e
puts e
end
end
【问题讨论】:
-
欢迎来到 Stack Overflow。您是在向我们征求意见或答案吗?类似“SQL 注入”的情况是用户输入表达式而您盲目地执行它。如果您的表达式是由您的代码生成的或来自已知的良好来源,那么您是安全的。您的正则表达式将不起作用,因为空格在模式中很重要。有一面旗帜让他们变得无足轻重。你可以弄清楚它是什么。
-
检查表达式的语法正确性通常通过将表达式转换为前缀或后缀形式来完成。不确定正则表达式是正确的工具。如果您不想重新发明*,似乎还有一个 Ruby 库来构建解析器 - github.com/nathansobo/treetop
-
大家好,谢谢大家。我最终做了一些更简单的事情。