美文网首页
re模块及利用正则进行计算器的设计

re模块及利用正则进行计算器的设计

作者: 陌小衫 | 来源:发表于2018-03-10 10:12 被阅读0次

    简介

    正则表达式本身是一种小型的、高度专业化的编程语言,在python中被集成在re模块中,方便pythoner使用。

    字符含义

    元字符

    #   准备知识  re正则表达式
    # 元字符 . * $ ^ ( ) [ ] \ | + ?{ }
    
    # .表示任意一个字符
    # ret = re.findall('m.....r', 'monster') # monster
    # print(ret)
    
    # *修饰其前一个字符,可表示零个至多个
    # ret = re.findall('ter*', 'mmmonsterrrr')  # terrrr
    # print(ret)
    
    # \ 转义字符,使后一个字符改变原来的意思
    
    # + 和*的功能类似,匹配一个到多个
    # ret = re.findall('ter*', 'mmmonste')  # te
    # print(ret)
    
    # ^ 匹配字符串开头。在多行模式中匹配每一行的开头
    # ret = re.findall('^mmmo', 'mmmonstemmmo')  # mmmo
    # print(ret)
    
    # $匹配字符串末尾,在多行模式中匹配每一行的末尾
    # ret = re.findall('m..e$', 'monekmioe')  # mioe
    # print(ret)
    
    # ?修饰前一个字符表示0个或1个,本身不占位置
    # ret = re.findall('abc?', 'abc')     # abc
    # print(ret)
    # ret = re.findall('abc?', 'ab')     # ab
    # print(ret)
    
    # | 或。匹配|左右表达式任意一个,从左到右匹配,如果|没有包括在()中,则它的范围是整个正则表达式
    # ret = re.findall('abc|def', 'abcde')    # abc
    # print(ret)
    # ret = re.findall('abc|def', 'bcdef')    # def
    # print(ret)
    
    # [ ] 字符集。对应的位置可以是字符集中任意字符。字符集中的字符可以逐个列出,也可以给出范围,如[abc]或[a-c]。[^abc]表示取反,即非abc。
    # 所有特殊字符在字符集中都失去其原有的特殊含义。用\反斜杠转义恢复特殊字符的特殊含义。
    # ret = re.findall('a[bc]e', 'abed')     # abe
    # print(ret)
    # ret = re.findall('a[bc]e', 'aced')     # ace
    # print(ret)
    
    # { }  {m}匹配前一个字符m次,{m,n}匹配前一个字符m至n次,若省略n,则匹配m至无限次
    # ( )   被括起来的表达式将作为分组,从表达式左边开始没遇到一个分组的左括号“(”,编号+1.分组表达式作为一个整体,可以后接数量词。表达式中的|仅在该组中有效
    

    这里讲一下\(反斜杠)的作用:

    • 去除特殊含义,反斜杠后加元字符,会将元字符恢复成普通字符。
    • 实现特殊功能,反斜杠后加普通字符,实现特殊功能,当然只有一部分字符具有这样的功能(预定义字符)
    • 引用序号对应的字组所匹配的字符串。

    预定字符集

    # \d 数字[0-9]
    # \D 非数字[^\d]
    # \s 匹配任意空白字符:[<空格>\t\r\n\f\v]
    # \S 非空白字符[^\s]
    # \w 匹配包括下划线在内的任何字字符:[A-Za-z0-9_]
    # \W 匹配非字母字符,即匹配特殊字符
    # \A 仅匹配字符串开头,同^
    # \Z 仅匹配字符串结尾,同$
    # \b 匹配\w和\W之间,即匹配单词边界匹配一个特殊边界(比如单词和单词边界
    # \B [^\b]
    

    正则小应用

    能进行加减乘除以及括号优先级运算的计算器
    代码如下

    import re
    bracket = re.compile(r'\([^()]+\)')    # 寻找最内括号
    mul = re.compile(r'(\d+\.?\d*\*-\d+\.?\d*)|(\d+\.?\d*\*\d+\.?\d*)')   # 寻找乘法运算规则
    div = re.compile(r'(\d+\.?\d*/-\d+\.?\d*)|(\d+\.?\d*/\d+\.?\d*)')     # 寻找除法法则
    add = re.compile(r'(-?\d+\.?\d*\+-\d+\.?\d*)|(-?\d+\.?\d*\+\d+\.?\d*)') # 寻找加法法则
    sub = re.compile(r'(-?\d+\.?\d*--\d+\.?\d*)|(-?\d+\.?\d*-\d+\.?\d*)')  # 寻找减法法则
    c_f = re.compile(r'\(?\+?-?\d+\)?')  # 检查括号内是否运算完毕规则
    strip = re.compile(r'[^(].*[^)]')  # 脱括号规则
    
    
    # 计算表达式中乘法运算
    def Mul(s):
        exp = re.split(r'\*', mul.search(s).group())
        return s.replace(mul.search(s).group(), str(float(exp[0])*float(exp[1])))
    
    
    # 计算表达式中除法运算
    def Div(s):
        exp = re.split(r'/', div.search(s).group())
        return s.replace(div.search(s).group(), str(float(exp[0])/float(exp[1])))
    
    
    # 计算表达式中加法运算
    def Add(s):
        exp = re.split(r'\+', add.search(s).group())
        return s.replace(add.search(s).group(), str(float(exp[0])+float(exp[1])))
    
    # 计算表达式中减法运算
    def Sub(s):
        exp = sub.search(s).group()
        if exp.startswith('-'):
            exp = exp.replace('-', '+')
            res = Add(exp).replace('+', '-')
        else:
            exp = re.split(r'-', exp)
            res = str(float(exp[0])-float(exp[1]))
        return s.replace(sub.search(s).group(), res)
    
    
    def func():
        print("******---欢迎使用加减乘除计算器---******\n")
        while True:
            s = input("请键入需要计算的式子(q退出):")
            if s == 'q':
                break
            else:
                s = ''.join([x for x in re.split('\s+', s)])  # 删除字符串中的空格便于计算
                if not s.startswith('('):
                    # print(s)
                    s = str('(%s)' % s)    # 如果表达式首位无括号,则格式化表达式为:(表达式),方便最后一步计算
                    # print(s)
                    while bracket.search(s):    # 表达式存在括号,我们已经将表达式格式化为(表达式)
                        s = s.replace('--', '+')
                        s_temp = bracket.search(s).group()
                        if div.search(s_temp):   # 若除法运算存在(必须放在乘法之前)
                            s = s.replace(s_temp, Div(s_temp))
                        elif mul.search(s_temp):
                            s = s.replace(s_temp, Mul(s_temp))
                        elif sub.search(s_temp):
                            s = s.replace(s_temp, Sub(s_temp))
                        elif add.search(s_temp):
                            s = s.replace(s_temp,Add(s_temp))
                        elif c_f.search(s_temp):  # 若括号内无任何运算(类似(-2.32)除外)
                            s = s.replace(s_temp, strip.search(s_temp).group())
                        # print(s)
                    print('计算结果为: %.2f' % (float(s)))
    
    # class Main():
    #     def __init__(self):
    #         pass
    
    
    if __name__ == '__main__':
        func()
    

    运行测试结果:

    ******---欢迎使用加减乘除计算器---******
    
    请键入需要计算的式子(q退出):1+(2*(3+4)-4)/3
    (1+(2*(7.0)-4)/3)
    (1+(2*7.0-4)/3)
    (1+(14.0-4)/3)
    (1+(10.0)/3)
    (1+10.0/3)
    (1+3.3333333333333335)
    (4.333333333333334)
    4.333333333333334
    计算结果为: 4.33
    请键入需要计算的式子(q退出):
    

    重要的事说三遍,一定要检查正则匹配规则,一定要检查正则匹配规则,一定要检查正则匹配规则。

    如有错误之处,欢迎斧正。

    欢迎关注微信公众号 待定程序猿
    不定期更新自己学习总结


    待定程序猿

    相关文章

      网友评论

          本文标题:re模块及利用正则进行计算器的设计

          本文链接:https://www.haomeiwen.com/subject/ayuufftx.html