2020-10-20-正则表达式

it2023-11-12  73

day16-正则表达式

二进制类型/字节(bytes)

其他数据转二进制:bytes(数据)

"""字符转二进制:字符串.encode(encoding='utf-8')""" print(bytes(10)) # b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' print(bytes(10.5)) # TypeError: cannot convert 'float' object to bytes print(bytes(True)) print(bytes('abc',encoding='utf-8')) """ 所有的数据都可以转为字符串,字符串又可以转二进制 """ """所有数据转二进制""" list1 = [1,5,3,'abc'] b1 = bytes(str(list1),encoding='utf-8') print(b1) """二进制转字符串""" str1 = str(b1,encoding='utf-8') pirnt(str1) """再将字符串转原序列""" list1 = eval(str1) print(list1) '-------------------------------------------------------------------' # 编码 """字符串转二进制""" str2 = 'hello' b1 = str2.encode(encoding='utf-8') print(b1) # b'hello' # 解码 """二进制转字符串""" str1 = b1.decode(encoding='utf-8') print(str1) # hello
正则语法

什么是正则表达式

""" 正则表达式是一种工具:一中专门用来做字符串匹配的工具,能够在某些情况下让字符串的处理变得非常简单 正则是用来描述字符串规则 fullmatch(正则表达式,字符串) - 判断正则表达式是否与字符串完全匹配,如果不匹配返回None """

正则表达式的语法

1.匹配字符

"""普通字符在正则表达式中表示这个符号本身""" # 1)普通字符 # 2). - 匹配 # 3)\d - 匹配任意一个数字字符 # 4)\D - 匹配任意一个非数字字符 # 5)\s - 匹配任意一个空白字符:空格,换行(\n),\t # 6)\S - 匹配任意一个非空白字符 # 7)\w(没用) # 8)[字符集] - 匹配字符集中出现的任意一个字符 """ 注意:一个[]只能匹配一个字符 [abc] - 匹配一个字符是a or b or c [\dabc] - 匹配一个字符是数字或者是 a or b or c - - 在[]中两个字符之间才有特殊意义 [0-9] - 匹配0-9任意一个数字字符 [a-z] - 匹配任意一个小写字母 [a-zA-Z] - 匹配任意个一个字母 [\da-zA-Z_] - 匹配字母、数字、下划线 [\u4e00-\u9fa5] - 匹配任意一个中文字符 """ # 9)[^字符集] - 匹配不在字符集中的任意一个字符集 """ 注意:^ 在[]中,如果没有在开头就表示这个符号本身 [^abc] - 匹配除了a,b,c 以外任意一个字符 [^0-9] - 匹配除了0-9以外的任意一个字符 [^\u4e00-\u9fa5] - 匹配除了中文以外的任意一个字符 """ # 匹配一个字符串又三个字符,分别是a、b、c re_str = r'abc' result = fullmatch(re_str,'abc') print(result) # <re.Match object; span=(0, 3), match='abc'> # 2). - 匹配任意一个字符 # 匹配一个长度是3的字符串,第一个字符是任意字符,后面是bc re_str = r'.bc' result = fullmatch(re_str,'1bc') print(result) # <re.Match object; span=(0, 3), match='1bc'> # 3)\d - 匹配任意一个数字字符 result = fullmatch(r'\d{3}','456') print(result) # <re.Match object; span=(0, 3), match='456'> print(fullmatch('\d{2}abc','45abc')) # <re.Match object; span=(0, 5), match='45abc'> # 4)\D - 匹配任意一个非数字字符 print(fullmatch(r'\d\D\d','4-6')) # <re.Match object; span=(0, 3), match='4-6'> # 5) \s - 匹配任意一个空白字符 # 空白字符: 空格、换行(\n)、\t print(fullmatch(r'abc\s123','abc 123')) # <re.Match object; span=(0, 7), match='abc 123'> print(fullmatch(r'abc\s123','abc\n123')) # <re.Match object; span=(0, 7), match='abc\n123'> print(fullmatch(r'abc\s123','abc\t123')) # <re.Match object; span=(0, 7), match='abc\t123'>

2.检测符号

""" 匹配符号要求一个符号必须对一个字符,会影响字符串的长度描述 检测符号,不会匹配字符,也不会影响字符串长度,他是在匹配成前提下,对指定的位置的字符进行检测 """ # 1) \b 检测是否是单词边界 # 单词边界:所有能够区分不同单词的符号,例如:空白字符,标点符号,字符串开头和字符串结尾 print(fullmatch(r'abc\b\s123','abc 123')) # <re.Match object; span=(0, 7), match='abc 123'> # 2) \B - 是否不是单词边界 print(fullmatch(r'abc\B123','abc123')) # <re.Match object; span=(0, 6), match='abc123'> # 3) ^ - 检测是否是字符串开头 print(fullmatch(r'^abc1123','abc123')) print(search(r'\d\d','lkjsljJL L L了久了45阿的说89法')) # <re.Match object; span=(15, 17), match='45'> print(search(r'^\d\d','lkjsljJL L L了久了45阿的说89法')) # None # 4) $ - 检测是否是字符串结尾 print(search(r'\d\d$','lkjsljJL L L了久了45阿的说89法')) # None print(search(r'\d\d$','lkjsljJL L L了久了45阿的说89')) # Process finished with exit code 0

3.匹配次数

# 1) * 0次或多次(任意次数) """ a* 字符a 常出现0次或者多次 \d* 任意数字可以出现多次(实质是\d可以出现多次) 如:315431328792.... [字符集]* 字符集中的任意字符出现0次或者多次(每次都可以是任意一个) """ print(fullmatch(r'a*bc','bc')) # <re.Match object; span=(0, 2), match='bc'> print(fullmatch(r'a\d*c','ac')) # <re.Match object; span=(0, 2), match='ac'> print(fullmatch(r'a\d*c','a5451353c')) # <re.Match object; span=(0, 9), match='a5451353c'> # 2) + - 1次或多次(至少一次) print(fullmatch(r'a+bc','bc')) # None # 3) ? - 0 次或1次 # 写一个正则能匹配任意正整数 print(fullmatch(r'[+]?[1-9]\d*','56')) # 4) {} """ {N} - 匹配N次 {M,N} - 匹配M到N次 {M,} - 匹配至少M次 {,N} - 最多N次 # 用户名的要求:全部由数字或者字母组成,长度是3-6位 print(fullmatch(r'[0-9a-zA-Z]{3,6}','55sf53')) # 5) 贪婪和非贪婪 在匹配次数不确定的时候匹配模式有两种,贪婪(默认)和非贪婪(在不确定次数后面加?) """ # 贪婪: print(search(r'a.+b','sjafls6ab554d6afsdfbsb6446a')) # <re.Match object; span=(2, 22), match='afls6ab554d6afsdfbsb' # 非贪婪模式: print(search(r'a.*?b','sjafls6ab554d6afsdfbsb6446a')) # <re.Match object; span=(2, 9), match='afls6ab'>

4.分组

""" 用法一:整体操作次数 a{2,3} (ab){2,3} 用法二:重复 \N 重复前面第N个分组中匹配到的内容 用法三:捕获 re中的findall在获取子串的时候,如果正则中有分组,只会获取分组匹配到的结果 """ # 两个数字两个字母的结构重复3到5次,类似:56vd65fd66re print(fullmatch(r'(\d{2}[a-z]{2}){3,5}','56vd65fd66re')) print(fullmatch(r'(\d)\1abc','88abc')) print(fullmatch(r'M(\d[a-z])N\1([A-Z])\2','M4aN4aNKK')) print(findall(r'a\d{2}b','a23b3133s1a22da32a55b1a2fb')) # ['a23b', 'a55b'] # 分组捕获 print(findall(r'a(\d{2})b','a23b3133s1a22da32a55b1a2fb')) # ['23', '55']

5.分支

# 1)| # 正则1|正则2|正则3|... #写一个正则能够匹配一个字符串:abc后面是三个数字或者是三个大写字母 print(fullmatch(r'abc(\d{3}|[A-Z]{3})','abc123'))

6.转义符号

""" 在正则中有特殊意义的符号前加\,让这个符号在正则中的功能消失 """ print(fullmatch(r'\d{2}\.\d{2}','12.36')) # <re.Match object; span=(0, 5), match='12.36'> # 注意:在正则中独立存在有特殊意义的符号,放在[]中,它的意义会自动消失 # . + * ?
re模块的使用
# 1.re.compile(正则表达式对象) - 编译正则表达式,返回正则对象 re_obj = re.compile(r'\d{3}') print(re_obj.fullmatch('123')) # <re.Match object; span=(0, 3), match='121' # 2.匹配 """ fullmatch(正则,字符串) - 让整个字符串和正则进行完全匹配,匹配失败返回None匹配成功返回匹配对象 match(正则,字符串) - 让字符串的开头和正则进行匹配,匹配失败返回None匹配成功返回匹配对象 """ # 匹配对象 result = re.match(r'(\d{2})([a-z]{3})([A-Z]{2})','32sdfAD阿凡达阿发') print(result) # <re.Match object; span=(0, 7), match='32sdfAD'> # 1)匹配到的子串 # 匹配对象.group() print(result.group()) # 32sdfAD # 有分组的情况 print(result.group(1)) # 32 print(result.group(2)) # sdf print(result.group(3)) # AD # 2 ) 匹配范围 - 匹配到的返回在在原字符串中的下标范围 # 匹配对象.span() print(result.span()) # (0, 7) print(result.span(2)) # (2, 5) - 第二个分组的范围 #3.查找 """ search(正则,字符串) - 扫描整个字符串,返回字符串中第一个匹配成功对象,找不到返回None findall(正则,字符串) - 获取字符串中所有满足正则的子串,匹配结果以列表返回,列表中的元素是字符串 finditer(正则,字符串) - 获取字符串中所有满足正则的子串,返回值是迭代器,迭代器中的元素匹配对象 """ # 没有分组 print(re.findall(r'\d{3}','lkadlfjjlkjlj21313as1d31sf222sf335af665')) # ['213', '222', '335', '665'] # 有一个分组的时候 (可以捕获 ) print(re.findall(r'a(\d{3})','lkadlfjjlkjlj21313as1d31sfa222sfa335af665')) # ['222', '335'] # 有两个或者两个以上的分组 (返回列表中的元素就不是字符串了) print(re.findall(r'([a-z]{2})(\d{3})','lkadlfjjlkjlj21313as1d31sf222sf335af665')) # [('lj', '213'), ('sf', '222'), ('sf', '335'), ('af', '665')] # 3)finditer() result = re.finditer(r'([a-z]{2})(\d{3})','lkadlfjjlkjlj21313as1d31sf222sf335af665') print(result) print(list(result)) # [<re.Match object; span=(11, 16), match='lj213'>, <re.Match object; span=(24, 29), match='sf222'>, <re.Match object; span=(29, 34), match='sf335'>, <re.Match object; span=(34, 39), match='af665'>] # 4) """ split(正则,字符串) - 将字符串中满足正则的子串作为切割点 sub(正则,字符串1,字符串2) - 将字符串2中满足正则的子串全部替换成字符串1 """ result = re.split(r'\d+','adfadsfasf665465ad4f56ad4fadf45') print(result) # ['adfadsfasf', 'ad', 'f', 'ad', 'fadf', ''] result = re.sub(r'\d+','+','adfadsfasf665465ad4f56ad4fadf45') print(result) # adfadsfasf+ad+f+ad+fadf+

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

1.用户名匹配

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

​ 2.不能以数字开头

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

import re user_name = input('输入用户名:') # user_name = '_sfa4513533sd0de' re_obj = re.compile(r'[a-zA-Z_][\da-zA-Z_]{5,15}') result = re_obj.fullmatch(user_name) print(result) 密码匹配

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

​ 2.必须以字母开头

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

password = 'd_0060_12.2' re_obj = re.compile(r'[a-zA-Z][^!@#¥%^&*\u4e00-\u9fa5]{5,11}') print(re_obj.fullmatch(password)) ipv4 格式的 ip 地址匹配 提示: IP地址的范围是 0.0.0.0 - 255.255.255.255 """ 任意1位或者2位数:0-99 任意以1开头的3位数:100-199 任意以2开头第二位数是0-4之间的的3位数:200-249 任意以25第3位数字在0-5之间的3位数字:250-255 首先满足第一条规则的正则是:\d{1,2} 首先满足第二条规则的正则是:1\d{2} 首先满足第三条规则的正则是:2[0-4]\d 首先满足第四条规则的正则是:25[0-5] r'(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}(\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5])' """ ipv = '209.209.209.209' re_obj = re.compile(r'(((\d{1,2})|(1\d{2})|(2[0-4]\d)|( 25[0-5]))\.){3}(\d{1,2})|(1\d{2})|(2[0-4]\d)|( 25[0-5])') print(re_obj.fullmatch(ipv)) # <re.Match object; span=(0, 15), match='209.209.209.209'> 提取用户输入数据中的数值 (数值包括正负数 还包括整数和小数在内) 并求和 例如:“-3.14good87nice19bye” =====> -3.14 + 87 + 19 = 102.86 data = '-3.14good87nice19bye' re_obj = re.compile(r'-?[1-9]\d*\.*\d*') list1 = re_obj.findall(data) result = reduce(lambda x,y: x+eval(y),list1,0) print(result) # 102.86 # 方法二: print(sum([eval(x) for x in list1])) # 102.86

验证输入内容只能是汉字

content = '阿的说法' re_obj = re.compile(r'[\u4e00-\u9fa5]*') print(re_obj.fullmatch(content)) # <re.Match object; span=(0, 4), match='阿的说法'>

匹配整数或者小数(包括正数和负数)

str_num = '-64523.3' re_obj = re.compile(r'[-+]?(0|[1-9]\d*|0\.\d+|[1-9]\d*\.\d+)') print(re_obj.fullmatch(str_num)) # <re.Match object; span=(0, 8), match='-64523.3'>

使用正则表达式获取字符串中所有的日期信息 匹配年月日日期 格式:2018-12-6

注意年的范围是1~9999, 月的范围是1~12, 日的范围是130或者131或者1~29(不考虑闰年)

""" 年: 一位数字:1-9 两位数字:10-99 任何一个以1开头3为数字:100-999 任何一个以1开头4为数字:1000-9999 满足第一条:[1-9] 满足第二条:[1-9]\d 满足第三条:[1-9]\d{2} 满足第四条:[1-9]\d{3} r'([1-9])|([1-9]\d)|([1-9]\d{2})|([1-9]\d{3})' 月 任何一位数字:1-9 任何以1开头的两位数字:12 满足第一条:[1-9] 满足第二条:1[0-2] r'([1-9])|(1[0-2])' 日 任何一位数字:1-9 任何以两位数字:10-29 任何以3开头的两位数字:30-31 满足第一条:[1-9] 满足第二条:[1-2]\d 满足第三条:3[0-1] r'([1-9])|([1-2]\d)|(3[0-1])' 1-31 r'([1-9])|([1-2]\d)|([3][0])' 1- 30 r'([1-9])|([1-2]\d)' 1-29 """ year = '2018-10-31' re_obj = re.compile(r'([1-9])|([1-9]\d)|([1-9]\d{2})|([1-9]\d{3})-(([1-9])|([1][0-2]))-((([1-9])|([1-2]\d))|(([1-9])|([1-2]\d)|([3][0])|(([1-9])|([1-2]\d)|(3[0-1]))))') print(re_obj.fullmatch(year))

替换字符串中的不良内容:将输入的内容中的不良内容全部替换成*(参考王者荣耀聊天要求)

re_str = r'[草日死妈]' result = re.sub(re_str,'*','safafs草你妈') print(result) # safafs*你*
最新回复(0)