• Python使用re实现计算器


      

    re 正则表达式 计算器

    海瑞博客-学习python之路•2016-12-01•Python 59• 0A+A-

    re是一门小型语言

    元字符

    .      通配符除了

    ^     以什么开始的匹配

    $     以什么结尾的匹配

    *     重复前一个条件,最少0个,[0,∞]

    +     重复前一个条件,最少1个,[1,∞]

    ?   重复前面的条件,最少0个,最多1个[0,1]

    {x}  重复前面的x次,x为数字,{x,y}最少x次,最多y-1次,{x,}最少x次,最多不限

    |     或的意思

    反斜杠后跟元字符去除特殊功能

        . 就是匹配点.

        + 匹配+

        \\ 匹配 等于 r“\"

        r是代表原生字符,不需要python转义就传入re

      反斜杠后跟普通字符实现特殊功能

        d 代表数字0-9  [0-9]

        D 代表非数字0-9 [^0-9]

        s 代表匹配空白字符[ fv] 

        S 代表匹配非空白字符 [^ fv]

        w 代表匹配非空白字符[a-zA-Z0-9]

        W 代表匹配非非字母和数字[^a-zA-Z0-9]

        d 代表匹配一个特殊边界,如匹配单词

    字符集

    [ ]代表字符集

        [a,b,c] 匹配a或b或c中任意一个

        [a-z]   匹配a到z中的任意小型字母 [A-Za-z0-9]

         - 代表什么到什么之间

        ^取反的意思,非

         将特殊符号转换成普通字符

        注:字符集内取消元字符的特殊功能( ^ -除外)

        [a-z,*] 匹配a-z的字母或*号,还有,号

        [^a-z] 匹配非a-z的字母的所有

    分组

      ()代表分组

        (1|2)  匹配1或2的字符

        (?P<id>w) 匹配一个字母或数字 这个组的名称是ID

        (:?d+) 取消分组的权限

    正则表达式方法

        findall(规则,字符串) 寻找所有满足规则的元素

        search(规则,字符串) 寻找第一个满足规则的元素并返回一个对象,配合group() 显示内容

    1 re.search("123","1jkj123asda").group() #不建议这样写,如果没找到会报错
    2 #建议以下方法
    3 a = re.search("123","1jkj123asda")
    4 if a:a = a.group()
    5 else:print("没有找到")
    search

        match(规则,字符串) 只在开始匹配规则,满足返回对象,不满足返回None

        split(规则,字符串) 通过规则分割字符串 注:先匹配第一个,并分割,再从第一个分割后的匹配第二个,并分割。。。

        sub(规则,新内容,字符串) 通过规则匹配字符串内容,并把匹配结果替换成新内容

        compile(规则) 将规则封装一个对象中,下次可以直接用对象查询,不需要输规则

        finditer(规则,字符串)将查找的结果成一个迭代器,使用next方法取,每个内容用group再取数

    习题:

    计算器

     要求可以计算+ - * ()**算法。

    计算公式:1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )

    思路:

    1. 判断字符串是否包含字母,两个点,括号不相等情况,并去除空白

    2. 提取字符串内的最里面的括号,并返回括号内容

    3. 传递替换 ++  +-  -+  --  *+  /+的操作

    4. 传入其他运算模块 **  // 等

    5. 传入 乘除模块进行计算  返回计算完毕的结果

    6. 传入 加减法模块 计算返回计算结果 返回最终结果

    7. 将结果替换括号,重复前2-7面步骤

    8. 直到无法检测出字符串内包含的+-*/  不包含最后结果

    9. 注意点:*-   /-的问题   负数+正数的问题处理  加减法和乘除法都要按照从左到右计算

    10. 海瑞博客 www.hairuinet.com
       1 #!/usr/bin/env python
       2 # -*- coding=utf-8 -*-
       3 # Created on:  2016年12月11日
       4 # @author: 郑建文
       5 # blog:www.hairuinet.com
       6 import re, time
       7 def hefaxin(xx):
       8     '''数据合法性'''
       9     b = 0
      10     for i in xx:  # 判断
      11         if b < 0:break
      12         if i == "(":b += 1
      13         elif i == ")":b -= 1
      14     zimu = re.search("[a-zA-Z=]", xx)  # 没有字母为空
      15     kh = len(re.findall("d+.?d*[(]", xx))  # 判断括号是否有  数字(的情况
      16     kh1 = len(re.findall("[()]", xx))  # 判断括号
      17     dian = re.search("(d+..d+)", xx)  # 判断是否有 ..
      18     if kh1 % 2 == b == kh and dian == zimu: return xx.replace(" ", "")
      19     return 0
      20 def tihfh(xx):
      21     '''符号替换'''
      22     xx = str(xx)
      23     xx = xx.replace("++", "+")
      24     xx = xx.replace("+-", "-")
      25     xx = xx.replace("-+", "-")
      26     xx = xx.replace("--", "+")
      27     xx = xx.replace("*+", "*")
      28     xx = xx.replace("/+", "/")
      29     return xx
      30 def ccf(xx):
      31     '''乘除法'''
      32     if re.search("(", xx): xx = xx[1:-1]  # 去括号
      33     while re.search("[*/]",xx):
      34         cenfa = re.search("d+.?d*[*/]{1}-?d+.?d*", xx)
      35         if cenfa:
      36             cenfa = cenfa.group()
      37             if cenfa.count("*") == 1:  # 一个乘法
      38                 a, b = cenfa.split("*")
      39                 xx = xx.replace(cenfa, str(float(a) * float(b)))
      40             elif cenfa.count("*") == 2:
      41                 a, b = cenfa.split("**")
      42                 xx = xx.replace(cenfa, str(float(a) ** float(b)))
      43             elif cenfa.count("/") == 1:
      44                 a, b = cenfa.split("/")
      45                 xx = xx.replace(cenfa, str(float(a) / float(b)))
      46             elif cenfa.count("/") == 2:
      47                 a, b = cenfa.split("//")
      48                 xx = re.sub(cenfa, str(float(a) // float(b)), xx)
      49         else:
      50             return xx
      51     return xx
      52 def jjf(xx):
      53     '''加减法,按匹配顺序计算'''
      54     if "(" in xx: xx = xx[1:-1]  # 去括号
      55     while re.search("d+.?d*[+-]d+.?d*",xx):
      56         findret = re.search("[-]?d+.?d*[+-]d+.?d*", xx)
      57         if findret:
      58             findret = findret.group()
      59             if re.search("d+.?d*+d+.?d*",findret):  # 加法
      60                 a, b = findret.split("+")
      61                 xx = xx.replace(findret, str(float(a) + float(b)))
      62             elif re.search("d+.?d*-d+.?d*",findret):  # 减法
      63                 a, b = findret.split("-")
      64                 xx = xx.replace(findret, str(float(a) - float(b)))
      65         else:return xx
      66     return xx
      67 def kuohao(xx):
      68     '''寻找括号'''
      69     xx = re.search("(([^()]+))", xx)
      70     if xx: return xx.group()  # 找到就返回找到结果
      71     return 0  # 没找到返回0
      72 if __name__ == '__main__':
      73     while True:
      74         jishuan = input("请输入公式,保留2位小数。
      绿色为正确,红色结果错误!
      >>>")
      75         db = hefaxin(jishuan)  # 合法性判断
      76         if db:  # 返回正确执行精算
      77             while db.count("(") > 0:  # 循环一直有括号的
      78                 kh = kuohao(db)  # 寻找括号
      79                 db = db.replace(kh, str(jjf(ccf(tihfh(kh)))))  # 替换括号
      80             else:  # 无括号的情况
      81                 ret = jjf(ccf(tihfh(db)))
      82                 if "+" in ret: ret = ret[1:]  # 取正数前面符号
      83                 while len(re.findall("d+.?d*[+-*/]+d+.?d*",ret)) > 0:
      84                     ret = jjf(ccf(tihfh(ret)))
      85             if eval(jishuan) == float(ret):s = 32  # 正确就显示绿色
      86             else:s = 31  # 错误就是红色
      87             print("33[%d;1m%s=%.2f
      33[1m" % (s, jishuan, float(ret)))
      88         else:print("33[31;1m程序不合法,无法计算!33[1m
      
      ")
      89 # 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )"
      90 #jishuan = "1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )"
      91 # 2*3*4*-1=6.0*-4.0
      计算器代码

      

    From Hairui 转载请注明出处!谢谢
  • 相关阅读:
    /etc/fstab 参数详解及如何设置开机自动挂载
    spring: 创建环绕通知
    spring: 使用Aspectj代理EnabelAspectjAutoProxy
    jsp: jstl标签库 uri标签
    jsp:jstl标签forTokens
    spring: @Pointcut给重复的注解/切点定义表达式
    js:for循环ul/li,获取当前被点击元素的id,以及给其他li设置属性
    jsp:forEach标签
    jsp:choose 、when 和 和 otherwise 一组标签
    windows7下docker配置镜像加速
  • 原文地址:https://www.cnblogs.com/hairuipython/p/6198590.html
Copyright © 2020-2023  润新知