海瑞博客

Python使用re实现计算器

  

re 正则表达式 计算器

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

re是一门小型语言

元字符

.      通配符除了\n

^     以什么开始的匹配

$     以什么结尾的匹配

*     重复前一个条件,最少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 代表匹配空白字符[\t\n\r\f\v] 

    \S 代表匹配非空白字符 [^\t\n\r\f\v]

    \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位小数。\n绿色为正确,红色结果错误!\n>>>")
    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\n\33[1m" % (s, jishuan, float(ret)))
    88         else:print("\33[31;1m程序不合法,无法计算!\33[1m\n\n")
    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
    计算器代码

     

  

posted @ 2016-12-19 18:28  海瑞PYthon  阅读(573)  评论(0编辑  收藏  举报
海瑞博客