总结
1. 检测类符号
-
\b - 检测是否是单词边界
""" 单词边界:凡是可以将两个单词分开的符号都是单词边界 例如:空白字符, 标点符号对应的字符, 字符串开头和结尾 注意:检测类符号实在匹配成功的情况下看检测类符号所在的位置是否符合要求 """ re_str = r'abc \b123' print(fullmatch(re_str, 'abc 123')) re_str = r'\b\d\d\b' result = findall(re_str, '99shij23阿松大 45 丢啊是67, 谁啊五年,89.达式90l 78') print(result) # ['45', '89', '78']
-
\B - 检测是否不是单词边界
re_str = r'\B\d\d\B' result = findall(re_str, '99shij23阿松大 45 丢啊是67, 谁啊五年,89.达式90l 78') print(result) # ['23', '90']
-
^ - 检测是否是字符串开头
re_str = r'^\d\d' result = findall(re_str, '99shij23阿松大 45 丢啊是67, 谁啊五年,89.达式90l 78') print(result) # ['99']
-
& - 检测是否是字符串结尾
re_str = r'\d\d$' result = findall(re_str, '99shij23阿松大 45 丢啊是67, 谁啊五年,89.达式90l 78') print(result) # ['78']
2. 匹配次数
-
* - 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')) # 0次 print(fullmatch(re_str, 'a3b')) print(fullmatch(re_str, 'a34b'))
-
+ - 1次或多次
print(fullmatch(re_str, 'ab')) # None 0次 print(fullmatch(re_str, 'a3b')) print(fullmatch(re_str, 'a34b'))
-
? - 0次或1次
re_str = r'[-+]?[1-9]\d' print(fullmatch(re_str, '+16')) print(fullmatch(re_str, '-16')) print(fullmatch(re_str, '16'))
-
{}
""" {N} - 匹配N次 {M,N} - 匹配M到N次,M和N都可以取到 {M,} - 匹配至少M次 {,N} - 匹配最多N次 """ re_str = r'1a{2,5}2' print(fullmatch(re_str, '1aaaaa2')) print(fullmatch(re_str, '1aa2'))
-
贪婪和非贪婪
""" 在匹配次数不确定的时候才有贪婪和非贪婪两种模式 贪婪:在能匹配成功的前提下取匹配次数最多的次数(默认) 非贪婪:在能匹配成功的前提下取匹配次数最小的次数(在匹配次数后加?) """ re_str = r'a.+b' # 贪婪 print(fullmatch(re_str, 'a各为其b123b')) print(match(re_str, 'aafbdabsdbasdb二二号认识')) re_str = r'a.+?b' # 非贪婪 print(match(re_str, 'aafbdabsdbasdb二二号认识'))
3. 分支和分组
-
分组 - ()
""" 用法1:将正则表达式中的一部分作为一个整体,进行整体相关操作,比如控制次数 用法2:重复-使用\M来重复前面第M个分组中的内容 """ re_str = r'([a-z]{3}\d{2}){3}' print(fullmatch(re_str, 'aqs12gdf45joi78')) re_str = '(\d{2}a){3}\d{2}' print(fullmatch(re_str, '22a34a56a43')) re_str = r'(\d\d)abc\1' print(fullmatch(re_str, '34abc34')) re_str = r'(\d{2})=([\u4e00-\u9fa5])=\2=\1' print(fullmatch(re_str, '12=是=是=12')) re_str = r'(\d{2})=\1=([\u4e00-\u9fa5])=\1' print(fullmatch(re_str, '12=12=去=12')) re_str = r'(\d{2})=\1=([\u4e00-\u9fa5])=\2' print(fullmatch(re_str, '12=12=去=去'))
-
分支 - |
""" 正则表达式1|正则表达式2 - 先让正则1和字符进行匹配,如果成功就成功,如果失就 和正则2进行匹配,如果正则2成功结果匹配成功,否匹 配失败(两个正则只有一个匹配成功就成功否则失败) """ re_str = r'\d{2}abc|[A-Z]{3}abc' print(fullmatch(re_str, '23abc')) print(fullmatch(re_str, 'MKHabc')) re_str = r'(\d{2}|[A-Z]{3})abc' print(fullmatch(re_str, '23abc')) print(fullmatch(re_str, 'MKHabc'))
-
转义符号: 在本身具备特殊功能或者特殊意义的符号前加,让其功能或者意义消失, 表示一个普通的符号
re_str = r'[1-9]\d\.\d{2}' print(fullmatch(re_str, '23.67')) re_str = r'\d\+\d' print(fullmatch(re_str, '3+5')) # 注意:独立具备特殊功能的符号在中括号中功能会自动消失.例如:+, *, ? # 本身在[]中有特殊意义的就要特别注意:^, -, [] re_str = r'\d[+]\d' print(fullmatch(re_str, '3+5')) re_str = r'\d[.]\d' print(fullmatch(re_str, '3.5')) re_str = r'\d[\^.]\d' print(fullmatch(re_str, '3.5')) re_str = r'\d[\[]]\d' print(fullmatch(re_str, '3[]5'))
4. re模块
-
compile(正则表达式) - 创建一个正则表达式对象
re_obj = re.compile(r'\d{3}') result = re_obj.fullmatch('123') print(result) print(fullmatch(r'\d{3}', '123'))
-
匹配类方法
""" 1)fullmatch fullmatch(正则表达式, 字符串) 正则表达式对象.fullmatch(字符串) 判断整个字符串是否符合正则表达式描述的规则,如果不符合返回None,符合返回匹配对象 2)match match(正则表达式, 字符串) 正则表达式对象.match(字符串) 判断字符串开头是否符合正则表达式描述的规则,如果不符合返回None,符合返回匹配对象 """
- 获取匹配结果
# 匹配对象.group() / 匹配对象.group(0) - 获取整个正则表达式匹配的结果 # 匹配对象.group(N) - 获取整个表达式中第N个分组匹配到的结果 result = match(r'\d{3}', '289爱神的箭asd-123') print(result) print(result.group()) # '289' result = match(r'((\d{3})-)([a-z]{2,5})', '134-asd爱神的箭asd-123') print(result.group(0)) # 134-asd print(result.group(1)) # 134- print(result.group(2)) # asd
- 获取匹配结果在原字符串中的位置
result = match(r'((\d{3})-)([a-z]{2,5})', '134-asd爱神的箭asd-123') print(result.span()) # [0, 7) print(result.span(3)) # [4, 7)
- 获取原字符串
# 匹配对象.string result = match(r'((\d{3})-)([a-z]{2,5})', '134-asd爱神的箭asd-123') print(result.string) # 134-asd爱神的箭asd-123
-
查找类方法
""" search(正则表达式, 字符串) 正则表达式对象.search - 获取字符串中第一个满足正则表达式的子串,如果没有返回None,否则返回匹配对象 """ result = search(r'\d{3}', 'asd23725刚好看见643ergw--ergwe挺好088') print(result) """ findall(正则表达式,字符串) 正则表达式对象.findall(字符串) - 获取字符串中所有满足正则表达式的子串,以列表的形式返回,列表中的元素是字符串 """ result = findall(r'\d{3}', 'asd23725刚好看见643ergw--ergwe挺好088') print(result) # ['237', '643', '088'] str1 = 'asd43而换个23634=-89jn7864阿斯弗6, 68d8791' result = findall(r'\d+', str1) print(result) # ['43', '23634', '89', '7864', '6', '68', '8791'] # 如果正则中有分组,findall只提取匹配结果中分组匹配到的内容 # 提取数字前面是汉字的数字 result = findall(r'[\u4e00-\u9fa5](\d+)', str1) print(result) # ['23634', '6'] result = findall(r'(\d+)-([a-z]+)', 'asas680-nm阿松大4-rwg==-781-ad=请问') print(result) # [('680', 'nm'), ('4', 'rwg'), ('781', 'ad')] result = [x[1] for x in result] print(result) """ finditer(正则表达式, 字符串) 正则表达式对象.finditer(字符串) - 获取字符串中所有满足正则表达式的子串,返回值是迭代器,迭代器中的元素是匹配对象 """ result = finditer(r'\d{3}', 'asd23725刚好看见643ergw--ergwe挺好088') print(list(result)) result = finditer(r'(\d+)-([a-z]+)', 'asas680-nm阿松大4-rwg==-781-ad=请问') print('整个正则匹配结果:', [x.group(0) for x in result]) result = finditer(r'(\d+)-([a-z]+)', 'asas680-nm阿松大4-rwg==-781-ad=请问') print('整个正则匹配结果:', [x.group(1) for x in result])
-
切割
""" split(正则表达式, 字符串, 最大切割数(切的次数)) 正则表达式对象.split(字符串) - 将字符串中所有满足正则表达式的子串作为切割点,对字符串进行切割 """ str1 = '供应过43尽快解3ljhl23刻录机sdf1145建立健3康jk阿964迪斯54=-的' result = split(r'\d+', str1) print(result) # ['供应过', '尽快解', 'ljhl', '刻录机sdf', '建立健', '康jk阿', '迪斯', '=-的'] str2 = '阿达,请问 请问强.儿童微软微软, 请问,企鹅舞. 请二位' result = split(r'[,\.]', str2) print(result) # ['阿达', '请问 请问强', '儿童微软微软', ' 请问', '企鹅舞', ' 请二位'] str3 = '阿达,请问 请问强.儿童微软微软, 请问,企鹅舞. 请二位' result = split(r'[,\.]', str3, 3) print(result) # ['阿达', '请问 请问强', '儿童微软微软', ' 请问,企鹅舞. 请二位']
-
替换
""" sub(正则表达式, 字符串1, 字符串2, 替换次数) 正则表达式对象.sub(字符串1, 字符串2) - 将字符串2中所有满足正则表达式的子串都替换成字符串1 """ result = sub(r'\d+', '+', '阿松大4文档145请问5如果二哥为8754===4啊') print(result) # 阿松大+文档+请问+如果二哥为+===+啊
5. 匹配参数
-
匹配参数
- 单行匹配和多行匹配
""" 默认是多行匹配 单行匹配和多行匹配的区别: 多行匹配的时候.不能和\n(换行)匹配;单行匹配的时候.可以和\n匹配 """ # 多行匹配 print(fullmatch(r'a.b', 'a\nb')) # None # 单行匹配(在正则表达式前加(?s)或者给flags赋值,flags=S) # S是从re模块中导入的 print(fullmatch(r'a.b', 'a\nb', flags=S)) print(fullmatch(r'(?s)a.b', 'a\nb'))
- 忽略大小写
""" 默认不忽略大小写 忽略大小写的时候,大写字母可以和对应的小写字母匹配,小写字母也可以和对应的大写字母匹配 """ print(fullmatch(r'[a-z]{3}123', 'hSm123')) # None # 忽略大小写(在正则表达式前加(?i)或者给flags赋值,flags=I) print(fullmatch(r'[a-z]{3}123', 'hSm123', flags=I)) print(fullmatch(r'(?i)[a-z]{3}123', 'hSm123', flags=I))
- 单行匹配和忽略大小写同时进行
print(fullmatch(r'abc.123', 'ABC\n123', flags=I|S)) print(fullmatch(r'(?si)abc.123', 'ABC\n123'))
6. 编程思想
-
类和对象
""" 什么是类:具有相同功能和相同属性的对象的集合 - 抽象的概念 什么是对象:对象就是类的实例 如果车是类,我家的那辆红色车就是对象 """
作业
利用正则表达式完成下面的操作:
一、不定项选择题
-
能够完全匹配字符串
"(010)-62661617"
和字符串"01062661617"
的正则表达式包括(ABD)A.
r"\(?\d{3}\)?-?\d{8}"
B.r"[0-9()-]+"
C.r"[0-9(-)]*\d*"
D.r"[(]?\d*[)-]*\d*"
-
能够完全匹配字符串“back”和“back-end”的正则表达式包括( ABCD )
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*” -
能够完全匹配字符串“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” -
能够在字符串中匹配“aab”,而不能匹配“aaab”和“aaaab”的正则表达式包括(BC )
A. r“a*?b”
B. r“a{,2}b”
C. r“aa??b”
D. r“aaa??b”
二、编程题
1.用户名匹配
要求: 1.用户名只能包含数字 字母 下划线
2.不能以数字开头
3.⻓度在 6 到 16 位范围内
re_str = r'(?i)[a-z\d_]{5,15}'
- 密码匹配
要求: 1.不能包含!@#¥%^&*这些特殊符号
2.必须以字母开头
3.⻓度在 6 到 12 位范围内
re_str = r'(?i)[a-z][^!@#¥%^&*]{5,11}'
- ipv4 格式的 ip 地址匹配
提示: IP地址的范围是 0.0.0.0 - 255.255.255.255
# 0~9:\d
# 10~99:[1-9]\d
# 100~199:1\d{2}
# 200~249:2[0-4]\d
# 250~255:25[0-5]
re_str = r'((\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])'
- 提取用户输入数据中的数值 (数值包括正负数 还包括整数和小数在内) 并求和
例如:“-3.14good87nice19bye” =====> -3.14 + 87 + 19 = 102.86
re_str = findall(r'-\d+\.\d+|\d+', '-3.14good87nice19bye')
result = sum([eval(x) for x in re_str])
print(result)
-
验证输入内容只能是汉字
re_str = r'[\u4e00-\u9fa5]+'
-
匹配整数或者小数(包括正数和负数)
re_str= r'[-+]?([1-9]\d*|0)(\.\d+)?'
-
验证输入用户名和QQ号是否有效并给出对应的提示信息
要求:
用户名必须由字母、数字或下划线构成且长度在6~20个字符之间
QQ号是5~12的数字且首位不能为0name_in = input('请输入用户名:') qq_in = input('请输入qq:') name_result = fullmatch(r'\w{6,20}', name_in) if name_result == None: print('用户名输入有误') else: print('用户名输入成功') qq_result = fullmatch(r'[1-9]\d{4,11}', qq_in) if qq_result == None: print('用户名输入有误') else: print('用户名输入成功')
-
拆分长字符串:将一首诗的中的每一句话分别取出来
poem = ‘窗前明月光,疑是地上霜。举头望明月,低头思故乡。’
poem = '窗前明月光,疑是地上霜。举头望明月,低头思故乡。' re_str = split(r'[,。]', poem) re_str.remove('') print(re_str)