一、正则表达式常用的字符集
[abc] 表示匹配a、b、c中的任意一个字符 [a-z] 表示匹配a到z之间的任意一个小写字母 [A-Z] 表示匹配A到Z之间的任意一个大写字母 [0-9] 表示匹配0到9之间的任意一个数字 [^abc] 表示匹配除了a、b、c之外的任意一个字符,^在字符集里表示取反 [0-9a-zA-Z] 表示匹配0-9之间、a-z之间、A-Z之间的任意某个字符 \d 匹配数字,即[0-9] \D 匹配非数字,即不是数字,[^0-9] \s 匹配空白,即 空格,tab键(制表符),换行符 \S 匹配非空白 \w 匹配非特殊字符,匹配任意一个字母、数字或下划线,相当于[a-zA-Z0-9_] \W 匹配特殊字符,匹配任意一个非字母、数字或下划线,相当于[^a-zA-Z0-9_]
二、 re模块的相关方法
1、re.match(pattern, string, flags=0)
res = re.match(r'\d+', '123abc123') # 返回一个对象
if res:
print(res) # <re.Match object; span=(0, 3), match='123'>
print(res.group(), type(res.group())) # 123 <class 'str'>
else:
print('不匹配')
2、re.search(pattern, string, flags=0)
# 返回匹配的第一个位置的值
res = re.search(r'\d+', "ab - 6 5xy")
if res:
print(res.group()) # 6
else:
print('不匹配')
3、re.findall(pattern, string, flags=0)
# 查找所有匹配的值,并返回一个存放匹配结果的列表
res = re.findall(r'\d+', '12abcd45lk09')
print(res) # ['12', '45', '09']
4、re.finditer(pattern, string, flags=0)
# 用于搜索字符串中与正则表达式匹配的所有子串,并返回一个迭代器。
# 取值需要用for循环 + group()
res = re.finditer(r'\d+', '45asd3')
for i in res:
print(i.group()) # 45 3
5、re.sub(pattern, repl, string, count=0, flags=0)
string = 'hello hello world'
res = re.sub('hello', 'hi', string)
print(res) # hi hi world
6、re.compile(pattern, flags=0)
# 用于编译正则表达式,并返回一个正则表达式对象。
pattern = re.compile(r'\d+') # 构造一个正则表达式对象
res = pattern.findall('121sdsd2121vvc12') # 使用编译后的正则表达式进行匹配
print(res) # ['121', '2121', '12']
三、小案例
1、案例:查找一个字符串中是否具有数字“8”
# res = re.search('8', '123876')
res = re.findall('8', '123876')
# res = re.finditer('8', '123876')
if res:
print(res) # 返回匹配的第一个结果
else:
print("没有")
2、案例2:查找一个字符串中是否具有数字
# re的多个方法都能查询
res = re.findall(r'\d', '12abcd45lk09')
print(res) # ['1', '2', '4', '5', '0', '9']
3、案例3:查找一个字符串中是否具有非数字
# 匹配非数字正则表达式是 '\D'
pattern = re.compile(r'\D')
res = pattern.findall('12nn2121j')
if res:
print(res) # ['n', 'n', 'j']
else:
print('没有')
四、元字符
元字符是正则表达式中的特殊字符,用来表示特定的字符或字符组合,用来表示特殊的匹配含义。
正则表达式练习:在线正则表达式测试 (oschina.net)
五、几个重要概念说明
1、子表达式(又称之为分组)
在Python的正则表达式中,子表达式是指使用小括号 ()
包裹起来的一部分表达式。
它们的作用主要有两个:
1)分组:子表达式可以将多个元素组成一个逻辑分组,以便于在匹配过程中进行重复操作、分析或引用。例如,(abc){2}
表示匹配两个连续的 "abc"。
2)捕获:子表达式还可以被捕获,以便于在匹配成功后获取到具体的值。捕获的内容可以通过编号或者使用命名分组来引用。
# 案例一
pattern = r'(ab)+'
string = 'ababab'
res = re.findall(pattern, string)
print(res) # 输出: ['ab']
# 案例二
res = re.search(r'\d(\d)(\d)', 'abcdef123ghijklmn')
print(res.group()) # 123
2、捕获
1)捕获指的是在正则表达式中使用小括号 ()
将匹配的部分包裹起来,以便后续引用或处理这部分内容。捕获的内容可以使用编号或命名分组进行引用。
2)在正则表达式的匹配过程中,当一个子表达式匹配到相应的内容后,计算机系统会自动将匹配到的内容保存在一个特定的数据结构中,通常称为捕获组的缓存区。
3))在 Python 中,通过 re
模块进行正则表达式的匹配,可以通过 group(n)
方法来访问捕获的内容,其中 n
为捕获组的编号。
# 捕获
pattern = r'(\d{2})-(\d{2})-(\d{4})'
match = re.search(pattern, '31-12-2022')
print(match.group(1)) # 输出: 31
print(match.group(2)) # 输出: 12
print(match.group(3)) # 输出: 2022
3、命名分组
1)命名分组是在正则表达式中为捕获组添加名称的一种方式,它能够使得引用和处理捕获的内容更加清晰和直观。
2)命名分组的语法格式:(?P<name>pattern),name
是你希望为该捕获组指定的名称,pattern
是该捕获组的正则表达式模式。
# 命名分组
pattern = r'(?P<one>\d{2})-(?P<two>\d{2})-(?P<three>\d{4})'
match = re.search(pattern, '31-12-2022')
print(match.group('one')) # 输出: 31
print(match.group('two')) # 输出: 12
print(match.group('three')) # 输出: 2022
4、反向引用
1)反向引用是正则表达式中的一种功能,它允许引用先前捕获的内容。通过反向引用,可以在正则表达式中使用前一个捕获组所匹配到的内容。
2)反向引用的语法格式如下:\N,\N
是一个特殊的转义序列,表示引用编号为 N
的捕获组的内容。
# 从左往右,第一个小括号称为第一个匹配组,以此类推
pattern = r'(\w)\1' # 匹配与第一个匹配组相同的内容
string = "hello goodd"
res = re.finditer(pattern, string)
for i in res:
print(i.group())
'''
结果:
ll
oo
dd
'''
5、练习
1)(正常)查找连续的四个数字,如:3569
答:\d\d\d\d或\d{4}
2)查找连续的相同的四个数字,如:1111
答:(\d)\1\1\1
3)查找数字,如:1221,3443
答:(\d)(\d)\2\1
4)查找字符,如:AABB,TTMM(提示:A-Z,正则:[A-Z])
答:([A-Z])\1([A-Z])\2
5)查找连续相同的四个数字或四个字符(提示:\w)
答:(\w)\1\1\1
六、综合练习
1、需求:在列表中["apple", "banana", "orange", "pear"],匹配apple和pear
lis = ["apple", "banana", "orange", "pear"]
lis_str = str(lis) # 将整个列表转成字符串,包括中括号
res = re.findall(r'apple|pear', lis_str)
print(res) # ['apple', 'pear']
2、需求:匹配出163、126、qq等邮箱号。
# 匹配邮箱
email = '1478670@qq.com, go@126.com, heima123@163.com'
res = re.finditer(r'\w+@(qq|126|163).com', email)
if res:
for i in res:
print(i.group())
else:
print('无匹配邮箱')
'''
结果是:
1478670@qq.com
go@126.com
heima123@163.com
'''
3、匹配一个 URL
pattern = r'https?://\w+(\.\w+)+'
string = 'url is https://www.example.con'
res = re.search(pattern, string)
print(res.group())
'''
https?: 表示匹配http或https
\w: 表示匹配一个或多个字符
(\.\w)+: \.表示转义,就是一个点(.), 总体表示匹配一个或多个'.xxx'这样的字符串
'''
4、匹配日期
pattern = r'\d{4}-\d{2}-\d{2}'
string = 'Today is 2024-07-08'
res = re.search(pattern, string)
print(res.group()) # 2024-07-08
5、匹配一个 IP 地址
# ip地址的每一位的范围都是0~255,所以匹配的时候范围在1~3
pattern = r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
string = "ip is 192.169.10.10"
res = re.search(pattern, string)
print()
多练,多练,多练!!!