re模块练习

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

姓名        地区    身高    体重    电话
况咏蜜     北京    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开头,第二位为三、四、8 —— ^1[348]\\d{9},\\d第一个表示转义,'\d'为产生任意数字,{9}为刚好出现9次。ide

# -*- 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.验证邮箱是否合法spa

解析:邮箱必须有@符号,@符号前能够为字母、数字、下划线、中划线,@符号后通常为一到两个“.”中间为小写字母:3d

    表达式:code

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

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

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

          方括号后?表示前面内容能够出现一次或不出现。?后的\w+表示点号或连字符后面必须有其余字符。递归

          括号()后的*表示()内内容能够出现0次或屡次。ip

  @\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)'

  计算器思路:

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

  流程图:

 

# -*- 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
"""
相关文章
相关标签/搜索