week4:函数之正则表达式

一、正则表达式

string提供的方法是完全匹配

引入正则表达式是模糊匹配,内嵌在python中,通过调用Re模块来实现

二、字符匹配(普通字符,元字符):

普通字符:大多数字符和字母都会和自身匹配

re.findall('alex','yuanalesalexduye') ## 完全匹配

元字符:.   ^   $  *  +  ?   {}   []   |  () \

import re
ret = re.findall('w\w{2}l', 'hello world')  #['worl']
print(ret)
import re
#. 通配符
ret = re.findall('w..l', 'hello world')
print(ret)  ##['worl']  只能代指任意一个字符  不能代指换行符
import re
ret = re.findall('^w..l', 'wuylhello world')
print(ret)  ##['wuyl']  从开始匹配
import re
ret = re.findall('w..l$', 'wuylhello world')
print(ret)  ##[]  从结束匹配
import re
# * 重复匹配 [0 oo]  重复前面字符的个数 贪婪匹配
ret = re.findall('w.*l', 'wuylhello world')
print(ret)  ##
import re
# + 重复匹配 [1 oo]  贪婪匹配
ret = re.findall('w+l', 'wwlhello world')
print(ret)  ##
# ? 重复匹配 [0 1]
# {n} n匹配
#{n1,n2} n1 n2匹配 贪婪匹配
# [] 字符集  取消元字符的特殊功能(\ ^ -这3个字符例外)
import re
ret = re.findall('a[c,d]x', 'acx')
print(ret)##['acx']
#-放在[]里,代表范围
ret1 = re.findall('[a-z]x', 'acx')
print(ret1) #['cx']
ret3 = re.findall('[1-9a-zA-Z]', '12tyAS')
print(ret3) #['1', '2', 't', 'y', 'A', 'S']
ret4 = re.findall('[1-9,a-z,A-Z]', '12tyAS')
print(ret4) #['1', '2', 't', 'y', 'A', 'S']
#特殊字符. * 没有特殊意义
ret2 = re.findall('[w,*]x', 'acx')
print(ret2) #[]

#^放在[]里,代表取反
ret5 = re.findall('[^4,5]', 'ju12tyA5i4,us')
print(ret5) #['j', 'u', '1', '2', 't', 'y', 'A', 'i', 'u', 's']

# \ 后边跟元字符,去特殊功能
#\ 后边跟普通字符,实现特殊功能
ret6 = re.findall('\d{11}', 'ju12tyA5i498234567812345678')
print(ret6) #['j', 'u', '1', '2', 't', 'y', 'A', 'i', 'u', 's']
ret7 = re.findall(r'I\b', 'I am a LIST')
print(ret7) #['I']
#匹配出第一个满足条件的结果
ret8 = re.search('s.b', 'fjaskdseb')
print(ret8.group()) #seb

ret9 = re.search('a\.', 'agj')
print(ret9.group()) #此时没有匹配成功 

import re
# ()|
ret9 = re.search('(as)+', 'agjasas')
print(ret9.group())
ret10 = re.search('(as)|3', '3agjasas')
print(ret10.group())  ##3

 三、正则表达式的方法

1、findall()  所有的结果都返回到一个列表里

2、search() 返回匹配到的第一个对象(object),对象可以调用group返回结果

3、match()  只在字符串开始匹配,对象可以调用group返回结果

import re
ret = re.match('asd', 'asdfeuyrt')
print(ret.group())

4、split()

import re
ret = re.split('[j,s]', 'djksal')
print(ret)

 5、sub()

扫描二维码关注公众号,回复: 3623111 查看本文章
import re
ret = re.sub('a..x', 's..b', 'djkalexsal')
print(ret)  ##djks..bsal

 6.compile()

import re
obj = re.compile('.com')
ret = obj.findall('djkal.comexsal')
print(ret)  ##['.com']

四、正则表达式的应用

计算器的设计

import re

#格式化字符串
def format_string(string):
    string = string.replace('--', '+')
    string = string.replace('-+', '-')
    string = string.replace('++', '+')
    string = string.replace('+-', '-')
    string = string.replace('*+', '*')
    string = string.replace('/+', '/')
    string = string.replace(' ', '')
    return string


#检查表达式合法性
def check_expression(string):
    check_result = True
    #括号是否匹配
    if not string.count('(') == string.count(')'):
        print('表达式错误,括号未闭合')
        check_result = False
    if re.findall('[a-z]+]',string.lower()):
        print('表达式错误,包含非法字符')
        check_result = False

    return check_result


#计算乘除
def calc_mul_div(string):
    #从字符串中获取一个乘法或除法的表达式
    regular = '[\-]?\d+\.?\d*([*/]|\*\*)[\-]?\d+\.?\d*'
    #如果还能找到乘法或除法表达式
    while re.findall(regular, string):
        #获取表达式
        expression = re.search(regular, string).group()

        #如果是乘法
        if expression.count('*')==1:
            #获取要计算的两个数
            x, y = expression.split('*')
            #计算结果
            mul_result = str(float(x)*float(y))
            #将计算的表达式替换为计算结果值
            string = string.replace(expression, mul_result)
            #格式化以下
            string = format_string(string)


        #如果是除法
        if expression.count('/'):
            #获取要计算的两个数
            x, y = expression.split('/')
            #计算结果
            div_result = str(float(x)/float(y))
            #将计算的表达式替换为计算结果值
            string = string.replace(expression, div_result)
            #格式化以下
            string = format_string(string)


        if expression.count('*')==2:
            #获取要计算的两个数
            x, y = expression.split('**')
            pow_result=1
            for i in range(int(y)):
                pow_result *= int(x)
            string = string.replace(expression, str(pow_result))
            #格式化以下
            string = format_string(string)
    return string

#计算加减
def calc_add_sub(string):
    #定义正则表达式
    add_regula = '[\-]?\d+\.?\d*\+[\-]?\d+\.?\d*'
    sub_regula = '[\-]?\d+\.?\d*\-[\-]?\d+\.?\d*'


    #开始加法
    while re.findall(add_regula, string):
        #把所有的加法都算完,获取所有加法表达式
        add_list = re.findall(add_regula, string)
        for add_str in add_list:
            #获取两个加法的数
            x, y = add_str.split('+')
            add_result = '+' + str(float(x)+float(y))
            string = string.replace(add_str, add_result)
            string = format_string(string)

    # 开始减法
    while re.findall(sub_regula, string):
        #把所有的加法都算完,获取所有加法表达式
        sub_list = re.findall(sub_regula, string)
        for sub_str in sub_list:
            numbers = sub_str.split('-')
            #-3-5的情况,split会返回3个值
            if len(numbers) == 3:
                result = 0
                for v in numbers:
                    if v:
                        result -= float(v)
            else:
                x, y =numbers
                result = float(x)-float(y)
                #替换字符串

            string = string.replace(sub_str, '+' + str(result))
            string = format_string(string)
    return string


if __name__ == "__main__":

    source = "30-2*(6-3+(-9+2*3-4*4/2+6*3))"
    if check_expression(source):
        print('source:', source)
        print('eval result:', eval(source))
        source = format_string(source)
        print(source)

        while source.count('(') > 0:
            ## 格式化
            ##去括号,得到括号的字符串,结果如:(30+6/3)
            strs = re.search('\([^()]*\)', source).group()
            # 将括号的表达式进行乘除运算
            replace_str = calc_mul_div(strs)
            # 将括号的表达式进行加减运算
            replace_str = calc_add_sub(replace_str)
            # 将括号的字符串替换为计算结果,结果包含(),替换时去掉():[1:-1]
            source = format_string(source.replace(strs, replace_str[1:-1]))
        else:
            # 没有括号就到最后单一表达式了
            replace_str = calc_mul_div(source)
            # 算乘除
            replace_str = calc_add_sub(replace_str)
            # 算加减
            source = source.replace(source, replace_str)
        print('my result:', source.replace('+', ''))

输出结果:

source: 30-2*(6-3+(-9+2*3-4*4/2+6*3))
eval result: 10.0
30-2*(6-3+(-9+2*3-4*4/2+6*3))
my result: 10.0

猜你喜欢

转载自blog.csdn.net/MaHilda/article/details/82085291