zoukankan      html  css  js  c++  java
  • 正则表达式练习-计算器实现

    代码实现功能:

    运行代码,输入合法算术表达式,返回计算结果(在python终端中,能够算出结果的算术表达式,都支持)

    '''
    计算流程:
    1.将括号表达式(内部不包含括号)匹配出来
    2.计算括号表达式的值,用计算值替换原括号表达式
        计算处理流程:
        1)从左至右匹配,匹配出乘法或除法表达式,计算出值,塞回去替换匹配的内容
        2)乘除法运算都已处理完,对剩下表达式从左至右匹配
        3)匹配一个加法或减法运算式,计算出值,塞回去,替换匹配的表达式
        4)直到没有匹配运算式,停止,本轮括号表达式计算替换值流程完成
    3.再次进行括号表达式(内部不包含括号)匹配
    4.重复2
    5.直到匹配不出括号表达式,直接对剩余运算式进行乘除加减处理
    '''
    import re
    
    p1 = re.compile(r'+s*?-|-s*?+')  # 匹配'+-或-+' 匹配-+是为了处理用户输入原始表达式中有-+的情况
    p2 = re.compile(r'-s*?-')  # 匹配'--'
    
    
    def process_multi_divis(s):
        pattern = re.compile(r'-?d+(?:.?d+)?s*?[*/]{1}s*?-?s*?d+(?:.?d+)?')  # 匹配 *,/,*-,/- 四种情况
        while 1:
            result_process_p1 = re.sub(p1, '-', s)
            s = re.sub(p2, '+', result_process_p1)
            r = re.search(pattern, s)
            if r:
                r = r.group()
                if '*' in r:
                    a, b = r.split('*')
                    result = float(a.strip()) * float(b.strip().replace(' ', ''))  # 5 *- 6这种表达式,去除负号与数字之间空格
                elif '/' in r:
                    a, b = r.split('/')
                    result = float(a.strip()) / float(b.strip().replace(' ', ''))
                s = s.replace(r, str(result))
            else:
                return s
    
    
    def process_plus_reduce(s):
        pattern = re.compile(r'-?d+(?:.?d+)?s*?[+-]{1}s*?d+(?:.?d+)?')
        while 1:
            result_process_p1 = re.sub(p1, '-', s)
            s = re.sub(p2, '+', result_process_p1)
            r = re.search(pattern, s)
            if r:
                r = r.group()
                if '+' in r:
                    a, b = r.split('+')
                    result = float(a.strip()) + float(b.strip())
                elif '-' in r:
                    if r.startswith('-'):  # 处理类似 -5-10 这种表达式
                        nums = r.split('-')
                        a, b = nums[1], nums[2]
                        result = - float(a.strip()) - float(b.strip())
                    else:
                        a, b = r.split('-')
                        result = float(a.strip()) - float(b.strip())
                s = s.replace(r, str(result), 1)  # 只替换一次,避免遇到1+1+1+1这样的表达式,发生多次替换的情况
            else:
                return s
    
    
    def process_parentheses(s):
        pattern = re.compile(r'([^(]+?)')  # 匹配最内层括号
        while 1:
            r = re.findall(pattern, s)
            if r:
                for item in r:
                    expression = item[1:-1]  # 去掉首尾括号
                    r1 = process_multi_divis(expression)  # 处理乘除法
                    r2 = process_plus_reduce(r1)  # 处理加减法
                    s = s.replace(item, r2)  # 处理完成,替换计算结果后,表达式中可能会存在'+-','--'这种运算符,需匹配进行替换; '+-'替换为'-','--'替换为'+'
                result_process_p1 = re.sub(p1, '-', s)
                s = re.sub(p2, '+', result_process_p1)
            else:
                return s
    
    
    def main():
        expression = input('请输入要计算的表达式:')
        result_step1 = process_parentheses(expression)  # 处理内层括号
        result_step2 = process_multi_divis(result_step1)  # 计算乘除法
        final_result = process_plus_reduce(result_step2)  # 计算加减法
        print('计算结果:', final_result)
    
    
    if __name__ == '__main__':
        main()
  • 相关阅读:
    面试题收集——Java基础部分(一)
    Eclipse在线安装SVN
    一、 Log4E插件下载
    MyEclipse使用总结——MyEclipse中配置WebLogic12c服务器
    MyEclipse使用总结——使用MyEclipse打包带源码的jar包
    MyEclipse使用总结——设置MyEclipse使用的Tomcat服务器
    MyEclipse使用总结——设置MyEclipse开发项目时使用的JDK
    MyEclipse使用总结——修改MyEclipse默认的Servlet和jsp代码模板
    MyEclipse使用总结——MyEclipse文件查找技巧
    CMSIS Example
  • 原文地址:https://www.cnblogs.com/gandoufu/p/9469633.html
Copyright © 2011-2022 走看看