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

2024-05-18 16:16:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我想拿出一个regax,它能够匹配存储在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))'

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


Tags: 字符串importre表达式match结尾字母模式
1条回答
网友
1楼 · 发布于 2024-05-18 16:16:15

您可以将其视为“拆分”字符串,并使用运算符作为分隔符。这将避免您试图在正则表达式中表示数字

因此,您只需要一个表达式来获取5个运算符和括号。这可以使用操作符之间的管道表示,最长的操作符(**)位于第一位

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

相关问题 更多 >

    热门问题