繁体   English   中英

数学表达式的正则表达式 Python

[英]Regular Expression for Mathematical Expression Python

我想提出一个能够匹配存储在exp中的数学表达式的正则表达式。

表达式的模式以括号开头和结尾,不能包含任何字母。 表达式可以包含整数或浮点数,运算符可以是+-*/** 表达式的长度不受限制。

这是我的正则表达式:

import re
re.match(r'^[(]([(-]?([0-9]+)[)]??)([(]?([-+/*]([0-9]))?([.]?[0-9]+)?[)])[)]*$', exp)

但是我的正则表达式与某些字符串不匹配。 例如:

  • exp = '(( 200 + (4 * 3.14)) / ( 2 ** 3 ))'
  • exp = '(23.23+23)'
  • exp = '((23**2)/23)'
  • exp = '(23.34-(3*2))'

我是正则表达式的新手,我不确定表达式的哪一部分是错误的,请原谅我的麻烦,希望有人能帮助我。 太感谢了!

您可以将其视为“拆分”字符串,而运算符是您的分隔符。 这将使您免于尝试在正则表达式中表示数字。

因此,您只需要一个能够选择 5 个运算符和括号的表达式。 这可以在运算符之间使用 pipe 来表示,最长的运算符 (**) 位于首位。

import re
symbols   = ["**","+","-","*","/","(",")"]    # longest first
tokens    = re.compile("("+"|".join(map(re.escape,symbols))+")")
            # placing symbols in a group makes re.split keep the separators

def tokenize(exp):
  parts = map(str.strip,tokens.split(exp)) # split and strip spaces
  return list(filter(None,parts))          # remove empty parts

exp = '(( 200 + (4 * 3.14)) / ( 2 ** 3 ))'
print(tokenize(exp))
['(', '(', '200', '+', '(', '4', '*', '3.14', ')', ')', '/', '(', '2', '**', '3', ')', ')']


exp = '(23.23+23)'
print(tokenize(exp))
['(', '23.23', '+', '23', ')']

exp = '((23**2)/23)'
print(tokenize(exp))
['(', '(', '23', '**', '2', ')', '/', '23', ')']

exp = '(23.34-(3*2))'
print(tokenize(exp))
['(', '23.34', '-', '(', '3', '*', '2', ')', ')']        

然后您可以执行第二遍并验证组件是运算符还是有效数字,并检查表达式是否具有匹配的括号和交替的运算符/操作数。 到那时,您将确切地知道表达式的哪一部分是不正确的。

例如:

def validate(exp):
    parts    = tokenize(exp)
    error    = ""
    pLevel   = 0
    previous = "$"
    for errorPos,part in enumerate(parts):
        pLevel += (part=="(")-(part==")")
        if pLevel<0: error="too many closing parentheses";break
        if part in "**+/)" and previous in "$**+-/(" :
            error = "missing operand";break 
        if part not in "**+-/)" and previous not in "$**+-/(":
            error = "missing operator";break
        previous = part
        if part in ["**","*","+","-","/","(",")"]: continue
        if all(p.isdigit() for p in part.split(".",1)): continue
        error = "invalid operand: " + part
        break
    if not error and pLevel!=0:
        errorPos,error = len(parts),"unbalanced parentheses"
    if not error and previous in "**+-/":
        errorPos,error = len(parts),"missing operand"
    if error:
        print("".join(parts))
        indent = " " * sum(map(len,parts[:errorPos]))
        print(indent+"^")
        print(indent+"|__ Error!",error)

...

validate('(( 200 + (4 * 3,14)) / ( 2 ** 3 ))')
                       
((200+(4*3,14))/(2**3))
         ^
         |__ Error! invalid operand: 3,14


validate('(( 200 + (4 * 3.14)) / ( 2 ** 3 )') 

((200+(4*3.14))/(2**3)
                      ^
                      |__ Error! unbalanced parentheses


validate('(( 200 + (4 * 3.14)))) / ( 2 ** 3 )') 

((200+(4*3.14))))/(2**3)
                ^
                |__ Error! too many closing parentheses


validate('(( 200 + *(4 * 3,14)) / ( 2 ** 3 ))')

((200+*(4*3,14))/(2**3))
      ^
      |__ Error! missing operand


validate('(( 200 + ()(4 * 3,14)) / ( 2 ** 3 ))')

((200+()(4*3,14))/(2**3))
       ^
       |__ Error! missing operand


validate('(( (200 + )(4 * 3,14)) / ( 2 ** 3 ))')

(((200+)(4*3,14))/(2**3))
       ^
       |__ Error! missing operand


validate('(( (200 + 2)(4 * 3,14)) / ( 2 ** 3 ))')

(((200+2)(4*3,14))/(2**3))
         ^
         |__ Error! missing operator

暂无
暂无

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

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