re模块练习

首先准备了一个通讯录文件:“嫩模联系方式”

姓名        地区    身高    体重    电话
况咏蜜     北京    171    48    13651054608
王心颜     上海    169    46    13813234424
马纤羽     深圳    173    50    13744234523
乔亦菲     广州    172    52    15823423525
罗梦竹     北京    175    49    18623423421
刘诺涵     北京    170    48    18623423765
岳妮妮     深圳    177    54    18835324553
贺婉萱     深圳    174    52    18933434452
叶梓萱    上海    171    49    18042432324
杜姗姗   北京    167    49       13324523342
通讯录文件

1.验证手机号是否合法

解析:手机号有11位,以1开头,第二位为3、4、8 —— ^1[348]\\d{9},\\d第一个表示转义,'\d'为产生任意数字,{9}为恰好出现9次。

# -*- coding:utf-8 -*-
__author__ = 'Qiushi Huang'

import re


class IsCellphone():
    def __init__(self):
        self.p = re.compile('^1[348]\\d{9}')  # 公式编译好了,直接拿去匹配提升效率

    def iscellphone(self, number):
        res = self.p.match(number)
        if res:
            return True
        else:
            return False


p = IsCellphone()
f = open("嫩模联系方式", "r")
data = f.read()
contacts = re.findall("[0-9]{11}", data)
for i in contacts:
    if p.iscellphone(i):
        print("%s 是正常号码" % i)
    else:
        print("请检查手机号码%s" % i)
"""
13651054608 是正常号码
13813234424 是正常号码
13744234523 是正常号码
请检查手机号码15823423525
18623423421 是正常号码
18623423765 是正常号码
18835324553 是正常号码
18933434452 是正常号码
18042432324 是正常号码
13324523342 是正常号码
"""

 

2.验证邮箱是否合法

解析:邮箱必须有@符号,@符号前可以为字母、数字、下划线、中划线,@符号后一般为一到两个“.”中间为小写字母:

    表达式:

re = "^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$"

  ^\w+:表示表达式以a-z,A-Z,0-9或下划线开头,带上“+”表示一次或多次出现。

  ([\.-]?\w+)*:方括号内包含字符\.- 是希望允许用户输入点号或连字符,但是点号对于正则表达式有特殊的意义,所以需要在它前面加上反斜杠\。

          方括号后?表示前面内容可以出现一次或不出现。?后的\w+表示点号或连字符后面必须有其他字符。

          括号()后的*表示()内内容可以出现0次或多次。

  @\w+:表示@符合,及@符号后必须有其他字符

  (\.\w{2,3})+:表示会出现一个点号,点号后面会出现字符(2到3个字符),后面的+表示点号和字符的组合会出现一次到多次

  $:正则表达式的末尾是一个美元符号$ ,表示匹配的字符串必须在这里结束

# 邮箱检查
class IsMail():
    def __init__(self):
        self.p = re.compile(r'^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$')

    def ismail(self, str):
        res = self.p.match(str)
        if res:
            return True
        else:
            return False


p = IsMail()
f = open("嫩模联系方式", "r")
for k,v in enumerate(f):
    if k == 0:
        pass
    else:
        data = v.split(" "*5)
        mail_addr = data[5]
        if p.ismail(mail_addr):
            print("正常得邮箱地址%s" % mail_addr)
        else:
            print("请检查邮箱地址%s" % mail_addr)
"""
正常得邮箱地址133123@qq.com

正常得邮箱地址wdasd@13.ad.asdw

请检查邮箱地址sadw@*sad2.asdw

正常得邮箱地址wddada@sina.com

正常得邮箱地址asddwa@adwd.adww

正常得邮箱地址adwwd2@12313.sadw

请检查邮箱地址asdwd2133@dedewd3

正常得邮箱地址asdwd2@dadwdw.dww

请检查邮箱地址adwdadw@dwdw..wda

请检查邮箱地址asdwd2@de13.d23*
"""

 

3.开发一个简单的python计算器,实现加减乘除及拓号优先级解析

  • 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),运算后得出结果,结果必须与真实的计算器所得出的结果一致
        hint:
    
        re.search(r'\([^()]+\)',s).group()#可拿到最里层的括号中的值 
    
        '(-40/5)'

  计算器思路:

    1、没用使用递归,先找出并计算所有括号里的公式,再计算乘除和加减
    2、所有的数字都认为是浮点型操作,以此来保留小数

  流程图:

 

# -*- coding:utf-8 -*-
__author__ = 'Qiushi Huang'

import re
import functools


def minus_operator_handler(formula):
    """处理一些特殊的减号运算"""
    minus_operators = re.split("-", formula)    # 以匹配到的字符当做列表分隔符
    calc_list = re.findall("[0-9]", formula)    # 把所有匹配到的字符放到以列表中的元素返回
    if minus_operators[0] == '':   # 第一个值为负号
        calc_list[0] = "-%s" % calc_list[0]
    res = functools.reduce(lambda x,y:float(x) - float(y), calc_list)
    print("\033[33;1m减号[%s]处理结果:\033[0m" % formula, res)
    return res


def remove_duplicates(formula):
    """删除重复的加减符号"""
    formula = formula.replace("++", "+")
    formula = formula.replace("+-", "-")
    formula = formula.replace("-+", "-")
    formula = formula.replace("--", "+")
    formula = formula.replace("- -", "+")
    return formula


def compute_multiply_and_dividend(formula):
    """算乘除法,传入的是字符串"""
    operators = re.findall("[*/]", formula)
    calc_list = re.split("[*/]", formula)
    res = None
    for index, i in enumerate(calc_list):
        if res:
            if operators[index-1] == "*":
                res *= float(i)
            elif operators[index-1] == "/":
                res /= float(i)
        else:
            res = float(i)

    print("\033[31;1m[%s]运算结果=\033[0m" % formula, res)
    return res


def handle_minus_in_list(operator_list, calc_list):
    """
    有的时候把算术符和值分开后,会出现这种情况  ['-', '-', '-'] [' ', '14969037.996825399 ', ' ', '12.0/ 10.0 ']
    这需要把第2个列表中的空格都变成负号并与其后面的值拼起来,恶心死了
    """
    for index, i in enumerate(calc_list):
        if i == '':   # 它其实是代表负号,改为负号
            calc_list[index+1] = i + calc_list[index+1].strip()


def handle_special_occactions(plus_and_minus_operators, multiply_and_dividend):
    '''有时会出现这种情况 , ['-', '-'] ['1 ', ' 2 * ', '14969036.7968254'],2*...后面这段实际是 2*-14969036.7968254,需要特别处理下,太恶心了'''
    for index,i in enumerate(multiply_and_dividend):
        i = i.strip()
        if i.endswith("*") or i.endswith("/"):
            multiply_and_dividend[index] = multiply_and_dividend[index] + \
                                           plus_and_minus_operators[index] + multiply_and_dividend[index+1]
            del multiply_and_dividend[index+1]
            del plus_and_minus_operators[index]
    return plus_and_minus_operators, multiply_and_dividend


def compute(formula):
    """这里的计算是去除括号的"""
    formula = formula.strip("()")   # 去除外面的括号
    formula = remove_duplicates(formula)   # 去除重复的+-号

    plus_and_minus_operators = re.findall("[+-]", formula)
    multiply_and_dividend = re.split("[+-]", formula)  # 取出乘除公式
    if len(multiply_and_dividend[0].strip()) == 0:   # 代表这肯定是个减号
        multiply_and_dividend[1] = plus_and_minus_operators[0] + multiply_and_dividend[1]
        del multiply_and_dividend[0]
        del plus_and_minus_operators[0]

    plus_and_minus_operators, multiply_and_dividend=handle_special_occactions(plus_and_minus_operators, multiply_and_dividend)
    for index, i in enumerate(multiply_and_dividend):
        if re.search("[*/]", i):
            sub_res = compute_multiply_and_dividend(i)
            multiply_and_dividend[index] = sub_res
    """开始运算+,-"""
    print(multiply_and_dividend, plus_and_minus_operators)
    total_res = None
    for index, item in enumerate(multiply_and_dividend):
        if total_res:   # 代表不是第一次循环
            if plus_and_minus_operators[index-1] == '+':
                total_res += float(item)
            elif plus_and_minus_operators[index-1] == '-':
                total_res -= float(item)
        else:
            total_res = float(item)
    print("\033[32;1m[%s]运算结果:\033[0m" %formula,total_res)
    return total_res


def calc(formula):
    """计算程序主入口,主要逻辑是先计算括号里的值,再计算乘除,再计算加减"""
    parenthesise_flag = True
    calc_res = None   # 初始化运算结果为None
    while parenthesise_flag:
        m = re.search("\([^()]*\)", formula)   # 找到最里层括号
        # <_sre.SRE_Match object; span=(18, 25), match='(-40/5)'>
        if m:
            print("先算括号里的值:", m.group())   # '(-40/5)'
            sub_res = compute(m.group())
            formula = formula.replace(m.group(), str(sub_res))
        else:
            print('\033[41;1m----没括号了...---\033[0m')

            print('\n\n\033[42;1m最终结果:\033[0m',compute(formula))
            parenthesise_flag = False   # 代表公式里的括号已经都被剥除了


if __name__ == '__main__':
    res = calc("1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )")

"""执行结果如下:
先算括号里的值: (-40/5)
[-40/5]运算结果= -8.0
[-8.0] []
[-40/5]运算结果: -8.0
先算括号里的值: (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )
[2*5/3 ]运算结果= 3.3333333333333335
[ 7 /3*99/4*2998 ]运算结果= 173134.50000000003
[10 * 568/14 ]运算结果= 405.7142857142857
['9', 3.3333333333333335, 173134.50000000003, 405.7142857142857] ['-', '+', '+']
[9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 ]运算结果: 173545.88095238098
先算括号里的值: (60-30 +-8.0 * 173545.88095238098)
[8.0 * 173545.88095238098]运算结果= 1388367.0476190478
['60', '30 ', 1388367.0476190478] ['-', '-']
[60-30 -8.0 * 173545.88095238098]运算结果: -1388337.0476190478
先算括号里的值: (-4*3)
[-4*3]运算结果= -12.0
[-12.0] []
[-4*3]运算结果: -12.0
先算括号里的值: (16-3*2)
[3*2]运算结果= 6.0
['16', 6.0] ['-']
[16-3*2]运算结果: 10.0
先算括号里的值: ( -1388337.0476190478 - -12.0/ 10.0 )
[12.0/ 10.0 ]运算结果= 1.2
['-1388337.0476190478 ', 1.2] ['+']
[ -1388337.0476190478 +12.0/ 10.0 ]运算结果: -1388335.8476190479
----没括号了...---
[ 2 * -1388335.8476190479]运算结果= -2776671.6952380957
['1 ', -2776671.6952380957] ['-']
[1 - 2 * -1388335.8476190479]运算结果: 2776672.6952380957


最终结果: 2776672.6952380957
"""

 

转载于:https://www.cnblogs.com/xiugeng/p/8886141.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值