简体   繁体   English

使用正则表达式计算数学表达式

[英]Evaluate a math expression with regex

I need to create a method that will receive a string containing a mathematical expression and has to:我需要创建一个方法来接收一个包含数学表达式的字符串,并且必须:

  • Validate it first.先验证一下。
  • Return the problem/problems, if they exist (for example, something like this: 4+3+4/0 or 4+4+(((2-2*4)- ).返回问题/问题,如果它们存在(例如,类似这样的: 4+3+4/04+4+(((2-2*4)- )。
  • If everything is ok, solve it and return the final value.如果一切正常,解决它并返回最终值。

What I've done so far was:到目前为止我所做的是:

  • I know that eval does exactly what I need, however it has the problem of SQL injection and so on.我知道eval正是我所需要的,但是它存在 SQL 注入等问题。
  • I discovered Regex.我发现了正则表达式。

I really don't know the best way to design this method for it to be safe and work with parenthesis, operators and numbers.我真的不知道设计这种方法的最佳方法是安全的并且可以使用括号、运算符和数字。 What I'm thinking is to use regex to check if the initial string is equal to the matched string.我在想的是使用正则表达式来检查初始字符串是否等于匹配的字符串。 If it is, I was thinking on using eval to calculate the final value.如果是,我正在考虑使用eval来计算最终值。 In your opinion is this the correct way to do it?在您看来,这是正确的做法吗?

Not being sure what I should do, I wrote:不确定我应该做什么,我写道:

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

This is returning:这是返回:

Let's Go
Empty string

I've seen Stack Overflow posts that this我看过 Stack Overflow 的帖子说这个

/\(* \s* \d+ \s* (( [-\+\*\/] \s* \d+ \)* \s* ) | ( [-\+\*\/] \s* \(* \s* \d+ \s* ))+/

would be the correct regex filter to use.将是正确的正则表达式过滤器使用。

What am I doing wrong?我究竟做错了什么? Should I change my approach?我应该改变我的方法吗?

Edit: I followed a different approach.编辑:我采用了不同的方法。 Do you think the following approach is safe?您认为以下方法安全吗?

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

You can't use a regular expression to identify correctly formed mathematical expressions.您不能使用正则表达式来识别正确形成的数学表达式。

A regular expression can in theory be matched with a finite state automaton, and the finite number of states of such an automaton can't keep track of the unbounded number of opening parentheses it might encounter.正则表达式理论上可以与有限状态自动机匹配,而这种自动机的有限状态数无法跟踪它可能遇到的无限数量的左括号。 The language of correctly matched parentheses is not a regular language .正确匹配括号的语言不是常规语言

What you can do is tokenize the string using regular expressions and then parse the token stream.您可以做的是使用正则表达式对字符串进行标记,然后解析标记流。

See also Regular expression for math operations with parentheses .另请参阅带括号的数学运算的正则表达式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM