2021.5.18 day16正则表达式和面向对象

2021.5.18 day16正则表达式和面向对象

检测类符号

1.\b 检测是否是单词边界
单词边界:凡是可以两个单词分开的符号都是单词边界,比如:空白符号,标点符号对应的字符,字符串开头和结尾
注意:检测类符号是在匹配成功的情况下看检测类符号所在的位置是否符合要求。

re_str = r'abc \b123'
print(fullmatch(re_str, 'abc 123'))
re_str = r'\b\d\d\b'
result = findall(re_str, 'shj23结合实际 45 计时开始67,数据,89.计算机90l 78')
print(result)

2.\B检测是否不是单词边界

re_str = r'\B\d\d\B'
result = findall(re_str, '99shj23结合实际 45 计时开始67,数据,89.计算机90l 78')
print(result)

3.^ 检测是否是字符串开头

re_str = r'^\d\d'
result = findall(re_str, '99shj23结合实际 45 计时开始67,数据,89.计算机90l 78')
print(result)

4.$ 检测是否是字符串结尾

re_str = r'\d\d$'
result = findall(re_str, '99shj23结合实际 45 计时开始67,数据,89.计算机90l 78')
print(result)
re_str = r'^\d\d\d$'
匹配次数
from re import fullmatch, match, search, findall
三个a: 'aaa'  == 'a{3}'
三个数字: '\d\d\d'  ==  '\d{3}'
2到5个大写字母: '[A-Z]{2,5}'

1.* 0次或者多次(任意次数)
a* - a出现0次或多次
\d* - \d出现0次或多次,每次的一个\d可以是任意一个数字
[abc]* - [abc]出现0次或多次,每次的[abc]都可以在a、b、c中任意选一个

re_str = r'a\d*b'
print(fullmatch(re_str, 'ab'))
print(fullmatch(re_str, 'a4b'))
print(fullmatch(re_str, 'a434510b'))

2.+ 一次或者多次(至少一次)

re_str = r'a\d+b'
print(fullmatch(re_str, 'ab'))   # None
print(fullmatch(re_str, 'a4b'))
print(fullmatch(re_str, 'a434510b'))

3.? 0次或1次

re_str = r'[-+]?[1-9]\d'
print(fullmatch(re_str, '+16'))
print(fullmatch(re_str, '-16'))
print(fullmatch(re_str, '16'))

4.{}
{N} - 匹配N次
{M,N} - 匹配M到N次,M和N都可以取到
{M,} - 匹配至少M次
{,N} - 匹配最多N次

re_str = r'1a{2,5}2'
print(fullmatch(re_str, '1aaaaa2'))
# 
re_str = r'1a{3}2'
print(fullmatch(re_str, '1aaa2'))

在匹配次数不确定的时候才有贪婪和非贪婪两种模式。
贪婪:在能匹配成功的前提下取匹配次数最多的次数。(默认)
非贪婪:在能匹配成功的前提下去匹配次数最少的次数。(在匹配次数后加?)

re_str = r'a.+?b'
print(fullmatch(re_str, 'a神兽金刚234b密码门b'))
print(match(re_str, 'asjsbhhhb123b脚手架水电费'))    # 3次  7次  11次
分组和分支

1.分组 - ()
用法1:将正则表达式中的一部分作为一个整体,进行整体相关操作,比如控制次数
用法2:重复-使用\M来重复前面第M个分组中的内容
用法3:捕获

# 'amn23abm45mnh78'
# re_str = r'[a-z]{3}\d{2}[a-z]{3}\d{2}[a-z]{3}\d{2}'
re_str = r'([a-z]{3}\d{2}){3}'
print(fullmatch(re_str, 'amn23abm45mnh78'))

# '22a34a56a43'
re_str = '(\d{2}a){3}\d{2}'
print(fullmatch(re_str, '22a34a56a43'))

# '34abc34'、 '78abc78'、'01abc01'
re_str = r'(\d\d)abc\1'
print(fullmatch(re_str, '12abc12'))
print(fullmatch(re_str, '12abc21'))   # None

re_str = r'(\d{2})=([\u4e00-\u9fa5])=\2=\1'
print(fullmatch(re_str, '12=好=好=12'))

re_str = r'(\d{2})=\1=([\u4e00-\u9fa5])=\2'
print(fullmatch(re_str, '34=34=是=是'))

2.分支
正则表达式1|正则表达式2 :先让正则1和字符进行匹配,如果成功就成功,如果失败就和正则2进行匹配;如果正则2成功结果匹配成功,否则匹配失败。(两个正则中只有一个可以匹配成功结果就成功,否则失败)

re_str = r'\d{2}abc|[A-Z]{3}abc'
print(fullmatch(re_str, '23abc'))
re_str = r'(\d{2}|[A-Z]{3})abc'
print(fullmatch(re_str, '23abc'))

3.转义字符:在本身具备特殊功能或者特殊意义的符号加\,让其功能或者意义消失,表示一个普通符号

# '23.67'、'90.01'
re_str = r'[1-9]\d\.\d{2}'
print(fullmatch(re_str, '19.37'))
# '2+8'
re_str = r'\d\+\d'
print(fullmatch(re_str, '6+7'))

注意:独立具备特殊功能的符号在[ ]中功能会自动消失,例如:+,*,?、.(、)等
本身在[ ]中有特殊意义的就要特别注意:^,-,[、]

re模块

1.compile(正则表达式) - 创建一个正则表达式对象

re_obj = compile(r'\d{3}')
result = re_obj.fullmatch('123')
print(result)

fullmatch(r'\d{3}', '123')
print(result)

2.匹配类方法
1)fullmatch(正则表达式,字符串)
正则表达式对象.fullmatch(字符串) -判断字符串是否符合正则表达式描述的规则,如果不符合返回None,符合返回匹配对象。
2)match(正则表达式,字符串)
正则表达式对象.match(字符串) - 判断字符开头是否符合正则表达式描述的规则,如果不符合返回None,符合返回匹配对象。

result = match(r'((\d{3})-)([a-z]{2,5})', '829-dhm技术交底㐇shs---23')
print(result)

1)获取匹配结果
匹配对象.group() / 匹配对象.group(0) - 获取整个正则表达式匹配到的结果
匹配对象.group(N) - 获取正则表达式中第N个分组匹配到的结果

print(result.group(0))   # '829-dhm'
print(result.group(1))   # '829-'
print(result.group(2))   # '829'

2)获取匹配结果在原字符中的位置
匹配对象.span()
匹配对象.span(N)

print(result.span())    # [0, 7)
print(result.span(3))   # [4, 7)

3)获取原字符串
匹配对象.string

print(result.string)    # '829-dhm技术交底㐇shs---23'
  1. 查找类方法方法
    “”"
    search(正则表达式, 字符串)
    正则表达式对象.search(字符串) - 获取字符串中第一个满足正则表达式的子串,如果没有返回None,否则返回匹配对象
result = search(r'\d{3}', 'shhs2728309990数据是992sjsj--sjss数据是099')
print(result)   # <re.Match object; span=(4, 7), match='272'>

findall(正则表达式, 字符串)
正则表达式对象.findall(字符串) - 获取字符串中所有满足正则表达式的子串, 以列表的形式返回,列表中的元素是字符串

str1 = 'shj24萨克斯38904=-37ml899计算机上3,90m7788'
result = findall(r'\d+', str1)   # ['24', '38904', '37', '899', '3', '90', '7788']
print(result)

result = findall(r'[\u4e00-\u9fa5]\d+', str1)
print(result)    # ['斯38904', '上3']

如果正则中有分组,findall只提取匹配结果中分组匹配到的内容

result = findall(r'[\u4e00-\u9fa5](\d+)', str1)
print(result)    # ['38904', '3']
result = findall(r'\d+-[a-z]+', 'hshs899-mn生死狙击2-mkl==-892-ma=计算机')
print(result)   # ['899-mn', '2-mkl', '892-ma']
result = findall(r'\d+-([a-z]+)', 'hshs899-mn生死狙击2-mkl==-892-ma=计算机')
print(result)    # ['mn', 'mkl', 'ma']

finditer(正则表达式, 字符串)
正则表达式对象.finditer(字符串) - 获取字符串中所有满足正则表达式的子串,返回值是迭代器,迭代器中的元素是匹配对象

str1 = 'shj24萨克斯38904=-37ml899计算机上3,90m7788'
result = finditer(r'\d+', str1)
print(list(result))


result = finditer(r'(\d+)-([a-z]+)', 'hshs899-mn生死狙击2-mkl==-892-ma=计算机')
print('整个正则匹配结果:', [x.group() for x in result])

result = finditer(r'(\d+)-([a-z]+)', 'hshs899-mn生死狙击2-mkl==-892-ma=计算机')
print('分组1的匹配结果:', [x.group(1) for x in result])

4.切割
split(正则表达式, 字符串)
正则表达式对象.split(字符串) - 将字符串中所有满足正则表达式的子串作为切割点对字符串进行切割
split(正则表达式, 字符串, 最大切割数)

str1 = '节省时间27计算机上9sjjsn6计算机0292jsjsn就几节课2-==解决'
result = split(r'\d+', str1)
print(result)    # ['节省时间', '计算机上', 'sjjsn', '计算机', 'jsjsn就几节课', '-==解决']

str2 = '失敬失敬,啥的看法和。适得府君书就,随叫随到加分号。是计算机上'
result = split(r'[,。]', str2)
print(result)    # ['失敬失敬', '啥的看法和', '适得府君书就', '随叫随到加分号', '是计算机上']

result = split(r'[,。]', str2, 3)
print(result)

5.替换
sub(正则表达式, 字符串1, 字符串2)
正则表达式对象.sub(字符串1, 字符串2) - 将字符串2中所有满足正则表达式的子串都替换成字符串1

result = sub(r'\d+', '+', '试试7数据09jsjs8989sj计算机上-=')
print(result)   # 试试+数据+jsjs+sj计算机上-=

result = sub(r'\d', '+', '试试7数据09jsjs8989sj计算机上-=')
print(result)   # 试试+数据++jsjs++++sj计算机上-=

result = sub(r'傻[bB逼]|f\s*u\s*c\s*k', '*', 'f u c k!')
print(result)

result = sub(r'\d', '+', '试试7数据09jsjs8989sj计算机上-=', 3)
print(result)   # 试试+数据++jsjs8989sj计算机上-=
匹配参数

匹配参数:1.单行匹配、2.忽略大小写
1.单行匹配和多行匹配
匹配参数:1.单行匹配、2.忽略大小写
1.单行匹配和多行匹配
默认是多行匹配。
多行匹配的时候.不能和\n(换行)匹配; 单行匹配的时候.可以和\n匹配
多行匹配

print(fullmatch(r'a.b', 'a\nb'))   # None

单行匹配
S是从re模块中导入的

print(fullmatch(r'a.b', 'a\nb', flags=S))   # <re.Match object; span=(0, 3), match='a\nb'>
print(fullmatch(r'(?s)a.b', 'a\nb'))    # <re.Match object; span=(0, 3), match='a\nb'>

2.忽略大小写
默认不忽略大小写。
忽略大小写的时候,大写字母可以喝对应的小写字母匹配,小写字母也可以和对应的大写字母匹配

print(fullmatch(r'[a-z]{3}123', 'hSm123'))    # None
# 忽略大小写
print(fullmatch(r'[a-z]{3}123', 'hSM123', flags=I))    # <re.Match object; span=(0, 6), match='hSM123'>
print(fullmatch(r'(?i)[a-z]{3}123', 'hSM123'))    # <re.Match object; span=(0, 6), match='hSM123'>

# 单行匹配和忽略大小写同时进行
print(fullmatch(r'abc.123', 'ABC\n123', flags=I|S))   # <re.Match object; span=(0, 7), match='ABC\n123'>
print(fullmatch(r'(?si)abc.123', 'ABC\n123'))   # <re.Match object; span=(0, 7), match='ABC\n123'>
编程思想

面向过程编程(穷人思想) - 逻辑+算法
函数式编程(小资思想) - 函数
面向对象编程(富豪思想) - 类和对象
1.类和对象
什么是类:具有相同功能和相同属性的对象的集合。 - 抽象的概念
什么是对象:对象就是类的实例

作业

利用正则表达式完成下面的操作:

一、不定项选择题
  1. 能够完全匹配字符串"(010)-62661617"和字符串"01062661617"的正则表达式包括(A、B、D )

A.r"\(?\d{3}\)?-?\d{8}"
B. r"[0-9()-]+"
C.r"[0-9(-)]*\d*"
D.r"[(]?\d*[)-]*\d*"

  1. 能够完全匹配字符串“back”和“back-end”的正则表达式包括(AB )
    A. r“\w{4}-\w{3}|\w{4}”
    B. r“\w{4}|\w{4}-\w{3}”
    C.r “\S±\S+|\S+”
    D. r“\w*\b-\b\w*|\w*”

  2. 能够完全匹配字符串“go go”和“kitty kitty”,但不能完全匹配“go kitty”的正则表达式包括(AD)
    A.r “\b(\w+)\b\s+\1\b”
    B. r“\w{2,5}\s*\1”
    C. r“(\S+) \s+\1”
    D. r“(\S{2,5})\s{1,}\1”

  3. 能够在字符串中匹配“aab”,而不能匹配“aaab”和“aaaab”的正则表达式包括(B )
    A. r“a*?b”
    B. r“a{,2}b”
    C. r“aa??b”
    D. r“aaa??b”

二、编程题

1.用户名匹配

​ 要求: 1.用户名只能包含数字 字母 下划线

​ 2.不能以数字开头

​ 3.⻓度在 6 到 16 位范围内

from re import *
username = 'abc1234'
result = fullmatch(r'(?i)[a-z_]\w{5,15}',username)
  1. 密码匹配

​ 要求: 1.不能包含!@#¥%^&*这些特殊符号

​ 2.必须以字母开头

​ 3.⻓度在 6 到 12 位范围内

from re import *
password = 'a234567'
result = fullmatch(r'(?i)[a-z][^!@#¥%^&*]{5,11}',password)
print(result)
  1. ipv4 格式的 ip 地址匹配
    提示: IP地址的范围是 0.0.0.0 - 255.255.255.255
from re import *
ip = '15.25.166.99'
result = ip.split(r'.',3)
for x in result:
    if  0 <= int(x) <= 255:
        print('ip地址匹配成功!')
        break
else:
    print('ip地址匹配失败!')
  1. 提取用户输入数据中的数值 (数值包括正负数 还包括整数和小数在内) 并求和
例如:“-3.14good87nice19bye” =====> -3.14 + 87 + 19 = 102.86
from re import *
str = '-3.14good87nice19bye'
result= findall(r'-?\d+[.]?\d+',str)
sum_result=sum([eval(x) for x in result])
print(sum_result)
  1. 验证输入内容只能是汉字

    str = '千峰'
    result = fullmatch(r'[\u4e00-\u9fa5]*',str)
    print(result)
    
  2. 匹配整数或者小数(包括正数和负数)

    from re import *
    num = '-88.66'
    result =fullmatch(r'[+-]?\d+|[+-]?\d+.?\d+', num)
    print(result)
    
  3. 验证输入用户名和QQ号是否有效并给出对应的提示信息

    要求:
    用户名必须由字母、数字或下划线构成且长度在6~20个字符之间
    QQ号是5~12的数字且首位不能为0

    name = input('请输入用户名:')
    qq = input('请输入QQ号:')
    result_name = fullmatch(r'\w{6,20}',name)
    result_qq = fullmatch(r'[1,9]\d{4,11}',qq)
    if result_name:
        print('用户名有效')
    else:
        print('用户名无效')
    if result_qq:
        print('QQ有效')
    else:
        print('QQ无效')
    
  4. 拆分长字符串:将一首诗的中的每一句话分别取出来

    ​ poem = ‘窗前明月光,疑是地上霜。举头望明月,低头思故乡。’

poem = '窗前明月光,疑是地上霜。举头望明月,低头思故乡。'
result = split(r'[,。]+', poem)
print(result)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值