正则表达式
正则表达式介绍正则表达式字符组正则表达式的特殊符号正则表达式量词正则表达式取消转义贪婪匹配、惰性匹配 re模块
re.findall() ---所有
findall 分组优先级 re.search() ---一个re.match()
match、search 分组 re.finditer()re.compile() ---编写正则表达式
正则表达式 正则表达式介绍正则表达式是一个特殊的字符序列,它可以检查一个字符串是否符合指定格式。
如果我们要筛选出一串纯数字的电话号码(假设为 13 15 17 开头)可以用以下俩种方法
方法一
user_phone = input('请输入您的手机号>>>: ').strip()
if len(user_phone) == 11 and user_phone.isdigit():
if user_phone.startswith('13') or user_phone.startswith('15') or user_phone.startswith('17'):
print('格式正确')
else:
print('不是 13 15 17 开头')
else:
print('格式错误')
方法二(正则表达式)
import re
user_phone = input('请输入您的手机号>>>: ').strip()
if re.match('^(13|15|17)[0-9]{9}$', user_phone):
print('格式正确')
else:
print('格式不正确')
相比之下方法二更简便。
正则表达式字符组我们要想测试正则表达式效果,我们可以借助一个工具,它的网址是 http://tool.chinaz.com/regex/
首先给定一个字符串: XWenXiang66iascb87a988jp0 当我们需要直接查找一个指定字符串(例如Xiang)的时候,只要直接输入 Xiang 即可(属于'字符匹配')。 当需要查找所有数字可以使用[0-9],会显示所有的数字等等...
需要注意的是,字符组默认一次只匹配一个字符,也就是说是逐个返回的。
| 正则表达式 | 作用 |
|---|---|
| [0123456789] | 匹配中括号内的任意一个数字 |
| [abcdefg…] | 匹配中括号内的任意一个字母 |
| [0-9] | 匹配任何数字 |
| [a-z] | 匹配任何小写字母 |
| [A-Z] | 匹配任何大写字母 |
| [a-zA-Z0-9] | 匹配任何字母及数字 |
| [^aeiou] | 除了aeiou字母以外的所有字符 |
| [^0-9] | 匹配除了数字外的字符 |
和字符组一样,特殊符号默认也是匹配一个字符。
| 正则表达式 | 作用 |
|---|---|
| . | 匹配除 “n” 之外的任何单个字符。 |
| d | 匹配一个数字字符。等价于 [0-9]。 |
| D | 匹配一个非数字字符。等价于 [^0-9]。 |
| s | 匹配任何空白字符,包括空格、制表符、换页符等等。 |
| S | 匹配任何非空白字符。 |
| w | 匹配数字字母下划线。等价于’[A-Za-z0-9_]’。 |
| W | 匹配非数字字母下划线。等价于 ‘[^A-Za-z0-9_]’。 |
| t | 匹配一个制表符 |
| ^ | 匹配字符串的开始 |
| $ | 匹配字符串的结尾 |
| ^$ | 俩个连用表示精确匹配,一样才行 |
| aIb | 匹配 a 或者 b 相当于 or(或)的意思 |
| () | 子表达式的开始和结束位置,相邻的选择项之间用竖杠分隔 |
| [] | 字符组的概念(里面所有的数据都是或的关系) |
| [^] | ^ 出现在了中括号的里面表示取反操作 |
给定一个字符串: XWenXiang66u87a98j . 会将字符串所有元素一个一个匹配出来 d 将所有数字匹配出来 # 6 6 8 7 9 8 D 不是数字的都被匹配出来 # X W e n X i a n g u a j s 没有空白字符,不匹配。 S 所有非空字符 # X W e n X i a n g 6 6 u 8 7 a 9 8 j w 匹配数字字母下划线。 # X W e n X i a n g 6 6 u 8 7 a 9 8 j W| 匹配非数字字母下划线。不匹配 t 匹配一个制表符,不匹配 ^ ^XWen 匹配 ^ea 不匹配 $ 98j$ 匹配 98$ 不匹配 a|b X|u 将所有 X 或者 u 匹配出来 # X X u [] [Xu] 和 X|u 一样将所有 X 或者 u 匹配出来 [^] [^Xu] 除了 X u 都被匹配正则表达式量词
前面都是以单个匹配,我们可以使用量词进行多个匹配。
"""量词必须跟在表达式的后面 不能单独使用 目的是增加匹配的字符数"""
| 正则表达式 | 作用 |
|---|---|
| * | 重复前面的子表达式零次或者多次(默认就是多次,越多越好) |
| + | 重复前面的子表达式一次或者多次(默认就是多次,越多越好) |
| ? | 重复前面的子表达式零次或者一次(默认就是一次,越多越好) |
| {n} | 重复n次 |
| {n,} | 重复最少n次(越多越好) |
| {n,m} | 重复n到m次(越多越好) |
给定一个字符串: 熊大和熊二在打熊三
.* 重复匹配除了n的所有字符,并匹配成一串 # 熊大和熊二在打熊三
.+ 也是重复匹配成一串,因为默认也是多次。
.? 和 . 的结果一样,默认单个匹配
.{3} 是重复5次匹配也就是5个一组了。 # 熊大和 熊二在 打熊三``
.{5,} 默认重复多次匹配,也就是和 .* 一样 # 熊大和熊二在打熊三
熊.? 相当于 熊. # 熊大 熊二 熊三
熊.* 匹配以熊开头的所有字符 # 熊大和熊二在打熊三
熊.+ 和熊.*一样
熊.{2} 可以理解为匹配 满足熊..的字符串 # 熊大和 熊二在
熊.{2,} 重复无限次. # 熊大和熊二在打熊三
熊.{1,2} 以熊开头重复最少1次最多2次 . # 熊大和 熊二在 熊三
熊[大和二在]* 可以理解为给定字符串中熊开头后面的字符在括号里的有的话匹配出来# 熊大和 熊二在 熊
熊[^大和二在]* 取反,熊字开头后面的字符不在括号里的匹配出来 # 熊 熊 熊三
正则表达式取消转义
d 可以表示所有的数字,但有时候我们就想匹配 d 这个字符串并不作为功能,我们可以取消转义
使用俩个 \ 来取消转义 表达式 \d 此时表示的是匹配 ‘d’ 这个字符串而不是匹配所有数字 类似我们如果要匹配 \d 这个字符我们可以使用 \\d 来匹配... 在 python 中还可以在字符串的前面加' r '取消转义贪婪匹配、惰性匹配
贪婪匹配就是匹配到最大长度,惰性匹配就是匹配到结果就行,惰性匹配后加上 ?
例子 给定的文本re模块vhgcg
<.*> 使用这种方式会从第一个括号开始到最后一个括号结束,中间的括号忽略,为贪婪匹配。 匹配结果vhgcg
<.*?> 这种方法从第一个括号开始,遇到一个结束括号就结束,为惰性匹配。 匹配结果贪婪和惰性通常都是利用左右两边的条件作为筛选依据
在python中无法直接使用正则 需要借助于 re 模块或者第三方其他模块
re.findall() —所有在字符串中找到正则表达式所匹配的所有子串,并返回一个列表。没有找到匹配的,则返回空列表
语法格式 re.findall(pattern, string, flags=0) pattern 匹配的正则表达式 string 要匹配的字符串。
代码示例
import re
res = re.findall('a', 'asavdasv')
print(res)
打印结果
['a', 'a', 'a']
findall 分组优先级
1. 使用 findall 方法时,正则表达式中如果有括号()分组,那么在展示匹配结果的时候,默认演示'''括 号内正则表达式匹配到的内容'''。
代码示例一
import re
print(re.findall('.*?', 'hello'))
print(re.findall('(.*?)', 'hello'))
打印结果
['hello']
['hello']
代码示例二
import re
res = re.findall('(au)(aa)','auaau')
print(res)
打印结果
[('au', 'aa')]
2. 我们也可以用 '?:' 取消默认演示括号里内容
代码示例
import re
print(re.findall('.*?', 'hello'))
print(re.findall('(.*?)', 'hello'))
print(re.findall('(?:.*?)', 'hello'))
打印结果
['hello']
['hello']
['hello']
re.search() —一个
匹配到一个符合条件的数据就结束,若是都没有符合条件则返回 None
语法格式 re.search(pattern, string, flags=0) pattern 匹配的正则表达式 string 要匹配的字符串。
代码示例
res1 = re.search('a', 'asavdasv')
print(res1)
print(res1.group())
打印结果
a
也就是说,只有调用了 group() 才能看到数据
还需要注意的是,如果字符串都没有满足正则表达式的条件,search 会返回 None 且此时调用方法 group
会报错
re.match()
从字符串的开头匹配,如果没有则直接返回 None 。类似于 ^
函数语法: re.match(pattern, string, flags=0) pattern 匹配的正则表达式 string 要匹配的字符串。
代码示例
res2 = re.match('a', 'asavdasv')
print(res2)
print(res2.group())
打印结果
a
和 search 一样也需要使用 group 方法取值。
若如下情况开头不符合正则表达式条件:
res2 = re.match('b', 'asavdasv')
print(res2)
print(res2.group())
此时会直接报错,因为开头不符合时,match 会返回 None ,且调用 group 会直接报错。
match、search 分组
match 和 search 使用括号可以分组,分完组可以在 group() 括号加索引获取分组内匹配到的数据
代码示例一
import re
res = re.search('a(u)','auaau')
print(res.group())
print(res.group(1))
打印结果
au
u
代码示例二
import re
res = re.match('a(u)','auaau')
print(res.group())
print(res.group(1))
打印结果
au
u
'''search和match有几个分组 group方法括号内最大就可以写几'''
分组之后还可以给组起别名
使用 '?P<>' 加在括号后面,可以给组起别名 <> 里面写别名。
代码示例
import re
res = re.match('(?Pau)(?Paa)','auaau')
print(res.group())
print(res.group(1))
print(res.group(2))
print(res.group('A'))
print(res.group('B'))
打印结果
auaa
au
aa
au
aa
re.finditer()
和 findall 类似,找到所有满足正则表达式匹配的条件的内容,并把它们作为一个迭代器返回。
语法格式 re.finditer(pattern, string, flags=0) pattern 匹配的正则表达式 string 要匹配的字符串。
代码示例
res3 = re.finditer('a', 'asavdasv')
print(res3)
for i in res3:
print(i.group())
打印结果
a
a
a
使用 finditer 返回的是迭代器,主要是为了节省空间。对于迭代器我们可以用 for循环取出元素,此时元
素需要调用 group() 才能取值。
re.compile() —编写正则表达式
提前写好后续需要经常使用的正则,生成一个正则表达式对象
语法格式 re.compile(pattern[, flags]) pattern : 一个字符串形式的正则表达式
代码示例
ojb = re.compile('d{2}.')
res4 = re.findall(ojb,'asd7342j3h4234bvhggea98')
print(res4)
打印结果
['734', '423']
首先定义一个变量用于接收正则表达式对象,并作为正则表达式参数传入 re.findall() 中。



