1 正则表达式的简介
1.1 概念
正则表达式是对字符串操作的⼀种逻辑公式,就是⽤事先定义好的⼀些特定字符、及这些特定字符的组合,组成⼀个“规则字符串”,这个“规则字符
串”⽤来表达对字符串的⼀种过滤逻辑
1.2 正则表达式的应⽤场景
表单验证(例如 : ⼿机号、邮箱、身份证… )
爬⾍
2 正则表达式对Python的⽀持
2.1 普通字符
字⺟、数字、汉字、下划线、以及没有特殊定义的符号,都是"普通字符"。正则表达式中的普通字符,在匹配的时候,只匹配与⾃身相同的⼀个字符。
例如:表达式c,在匹配字符串abcde时,匹配结果是:成功;匹配到的内容
是c;匹配到的位置开始于2,结束于3。(注:下标从0开始还是从1开始,因当前编程语⾔的不同⽽可能不同)
match()函数
- match(pattern, string, flags=0)
- 第⼀个参数是正则表达式,如果匹配成功,则返回⼀个match对象,否则返
回⼀个None - 第⼆个参数表示要匹配的字符串
- 第三个参数是标致位⽤于控制正则表达式的匹配⽅式 如: 是否区分⼤⼩写,多⾏匹配等等
import re
# 正则表达式
pattern = 'pythonn'
s = 'python and java'
result = re.match(pattern,s)
if result:
print(result)
else:
print('没有匹配到')
结果
没有匹配到
但是
import re
# 正则表达式
pattern = 'pythonn'
s = 'pythonn and java'
result = re.match(pattern,s)
if result:
print(result)
else:
print('没有匹配到')
及结果
<_sre.SRE_Match object; span=(0, 7), match='pythonn'>
然后
import re
# 正则表达式
pattern = 'pythonn'
s = 'pythonn and java'
result = re.match(pattern,s)
if result:
print(result.group()) # 匹配的那个内容 pythonn
print(result.start()) # 0
print(result.end()) # 7
print(result.span()) # (0, 7)
else:
print('没有匹配到')
还有
import re
# 正则表达式
pattern = 'pytho'
s = 'pythonn and java'
result = re.match(pattern,s)
if result:
print(result.group()) # 匹配的那个内容
# print(result.start()) # 0
# print(result.end()) # 7
# print(result.span()) # (0, 7)
else:
print('没有匹配到')
结果
pytho
2.2 元字符
正则表达式中使⽤了很多元字符,⽤来表示⼀些特殊的含义或功能

主要是一个字符
import re
re.match(r'a.c','abc').group()
Out[3]: 'abc'
re.match(r'a.c','aHc').group()
Out[4]: 'aHc'
re.match(r'a.c','a2c').group()
Out[5]: 'a2c'
re.match(r'a|c','a2c').group()
Out[6]: 'a'
re.match(r'a|c','b').group()
Traceback (most recent call last):
File "D:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2910, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-7-9b51cc7ff806>", line 1, in <module>
re.match(r'a|c','b').group()
AttributeError: 'NoneType' object has no attribute 'group'
从前开始匹配,如果前面没有,就报错
re.match(r'a|c','ac').group()
Out[8]: 'a'
re.match(r'a|c','ca').group()
Out[9]: 'c'
re.match(r'a|c','bac').group()
Traceback (most recent call last):
File "D:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2910, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-10-2ceb8f2fbfd0>", line 1, in <module>
re.match(r'a|c','bac').group()
AttributeError: 'NoneType' object has no attribute 'group'
re.search(r'a|b','cba').group()
Out[12]: 'b'
- [] 匹配字符集中的一个字符,也是最前面的
re.match(r'[abc]','bac').group()
Out[13]: 'b'
re.match(r'[abc]','abac').group()
Out[14]: 'a'
re.match(r'[abc]2','abac').group()
Traceback (most recent call last):
File "D:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2910, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-15-1730d91ab1a2>", line 1, in <module>
re.match(r'[abc]2','abac').group()
AttributeError: 'NoneType' object has no attribute 'group'
re.match(r'速度与激情[12345]','速度与激情3').group()
Out[16]: '速度与激情3'
re.match(r'速度与激情[12345]','速度与激情9').group()
Traceback (most recent call last):
File "D:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2910, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-17-4423406e6ef0>", line 1, in <module>
re.match(r'速度与激情[12345]','速度与激情9').group()
AttributeError: 'NoneType' object has no attribute 'group'
re.match(r'速度与激情[12345]','速度与激情12').group()
Out[18]: '速度与激情1'
- [^] 对字符集求反,也就是上面的反操作,尖号必须在方括号的最前面
re.match(r'速度与激情[^12345]','速度与激情9').group()
Out[20]: '速度与激情9'
- [-]是定义在[]里的一个字符区间,例如[a-z]
re.match(r'速度与激情[1-8]','速度与激情0').group()
Traceback (most recent call last):
File "D:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2910, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-21-da7d3948b175>", line 1, in <module>
re.match(r'速度与激情[1-8]','速度与激情0').group()
AttributeError: 'NoneType' object has no attribute 'group'
re.match(r'速度与激情[1-8]','速度与激情4').group()
Out[22]: '速度与激情4'
import re
re.match(r'速度与激情[1-8a-z]','速度与激情6a').group()
Out[5]: '速度与激情6'
- \对紧跟其后的一个字符进行转义,遇到特殊有含义的,最好转义一下
re.match(r'速度.与激情[a-z]','速度.与激情a').group()
Out[6]: '速度.与激情a'
re.match(r'速度\.与激情[a-z]','速度.与激情a').group()
Out[7]: '速度.与激情a'
re.match(r'速度.与激情[a-z]','速度a与激情a').group()
Out[8]: '速度a与激情a'
re.match(r'速度\.与激情[a-z]','速度a与激情a').group()
Traceback (most recent call last):
File "D:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2910, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-9-abaa268024ba>", line 1, in <module>
re.match(r'速度\.与激情[a-z]','速度a与激情a').group()
AttributeError: 'NoneType' object has no attribute 'group'
- * 直接打星号,打不出来,需要在星号前面加\才行。
- ⼀些⽆法书写或者具有特殊功能的字符,采⽤在前⾯加斜杠"\"进⾏转义的⽅法。

尚未列出的还有问号?、星号*和括号等其他的符号。所有正则表达式中具有特殊含义的字符在匹配⾃身的时候,都要使⽤斜杠进⾏转义。这些转义字符的匹配⽤法与普通字符类似,也是匹配与之相同的⼀个字符
2.3 预定义匹配字符集
正则表达式中的⼀些表示⽅法,可以同时匹配某个预定义字符集中的任意⼀个字符。⽐如,表达式\d可以匹配任意⼀个数字。虽然可以匹配其中任意字符,但是只能是⼀个,不是多个
- \d 0-9中任意一个数字 ,不能翻过来用
re.match(r'[1]23','123').group()
Out[10]: '123'
re.match(r'[1-3]','123').group()
Out[11]: '1'
re.match(r'\d','123').group()
Out[12]: '1'
re.match(r'123','\d').group()
Traceback (most recent call last):
File "D:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2910, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-13-cfb692470409>", line 1, in <module>
re.match(r'123','\d').group()
AttributeError: 'NoneType' object has no attribute 'group'
re.match(r'速度与激情\d','速度与激情7').group()
Out[18]: '速度与激情7'
- \w 任意一个字母数字下划线 A-Z,a-z,0-9,_
re.match(r'\w','a123').group()
Out[14]: 'a'
- \s 空格、制表符、换页符等空白字符的其中的任意一个
re.match(r'\s',' ').group()
Out[16]: ' '
re.match(r'\s','\t').group()
Out[17]: '\t'
- \D等于\d的反集,也就是非数字的任意一个字符,等同于[^\d]
re.match(r'速度与激情\D','速度与激情a').group()
Out[19]: '速度与激情a'
- \W等于\w的反集
re.match(r'速度与激情\W','速度与激情 ').group()
Out[20]: '速度与激情 '
- \S等于\s的反集
re.match(r'速度与激情\S','速度与激情d').group()
Out[21]: '速度与激情d'
2.4 重复匹配
-
前⾯的表达式,⽆论是只能匹配⼀种字符的表达式,还是可以匹配多种字符其中任意⼀个的表达式,都只能匹配⼀次。但是有时候我们需要对某个字段进⾏重复匹配,例如⼿机号码13666666666,⼀般的新⼿可能会写成
\d\d\d\d\d\d\d\d\d\d\d(注意,这不是⼀个恰当的表达式),不但写着费
劲,看着也累,还不⼀定准确恰当。 -
这种情况可以使⽤表达式再加上修饰匹配次数的特殊符号{},不但重复书写表达式就可以重复匹配。例如[abcd][abcd]可以写成[abcd]{2}

-
{n}表达式重复n次
re.match(r'\d{3}','123').group()
Out[22]: '123'
re.match(r'\d{3}','444').group()
Out[23]: '444'
- {m,n}表达式至少重复m次,最多重复n次
re.match(r'\d{3,4}-\d{7,8}','013-1234567').group()
Out[25]: '013-1234567'
re.match(r'\d{3,4}-\d{7,8}','013-123456789').group()
Out[26]: '013-12345678'
- {m,}表达式至少重复m次,但是\w在前面,后面要匹配的只能一个数字字母下划线这样
re.match(r'\w\d{3,}-\d{7,8}','ab013-12345678').group()
Traceback (most recent call last):
File "D:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2910, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-28-3e47a5d9d298>", line 1, in <module>
re.match(r'\w\d{3,}-\d{7,8}','ab013-12345678').group()
AttributeError: 'NoneType' object has no attribute 'group'
re.match(r'\w\d{3,}-\d{7,8}','a013-12345678').group()
Out[29]: 'a013-12345678'
re.match(r'\d\w{3,}-\d{7,8}','a013-12345678').group()
Traceback (most recent call last):
File "D:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2910, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-30-5d0843fe9e54>", line 1, in <module>
re.match(r'\d\w{3,}-\d{7,8}','a013-12345678').group()
AttributeError: 'NoneType' object has no attribute 'group'
re.match(r'\d\w{3,}-\d{7,8}','1a013-12345678').group()
Out[31]: '1a013-12345678'
re.match(r'\d\w{3,}-\d{7,8}','11aa-12345678').group()
Out[32]: '11aa-12345678'
re.match(r'\d\w{3,}-\d{7,8}','1aaaa-12345678').group()
Out[33]: '1aaaa-12345678'
- ?表示?前一个字符出现一次或者0次
re.match(r'\w[a-z]?','wdeco').group()
Out[34]: 'wd'
re.match(r'\w[a-z]?','w').group()
Out[35]: 'w'
- +表示匹配前一个字符出现至少出现一次,相当于{1,}
re.match(r'w[a-z]+','wdecas').group()
Out[37]: 'wdecas'
re.match(r'w[a-z]+','w').group()
Traceback (most recent call last):
File "D:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2910, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-38-8ab74144dee8>", line 1, in <module>
re.match(r'w[a-z]+','w').group()
AttributeError: 'NoneType' object has no attribute 'group'
- *表示出现0次到任意次,因为有换行,所以只匹配到第一行
html_content = '''asdsdsdsjdskdjssdshdasd
sdsijd
sjd
sd
'''
re.match(r'.*',html_content).group()
Out[41]: 'asdsdsdsjdskdjssdshdasd'
- 如果要多行匹配,需加上一个re.S
re.match(r'.*',html_content,re.S).group()
Out[42]: 'asdsdsdsjdskdjssdshdasd\nsdsijd \nsjd \nsd \n'
2.5 位置匹配和⾮贪婪匹配
位置匹配
有时候,我们对匹配出现的位置有要求,⽐如开头、结尾、单词之间等等

- ^在字符串开始的地方开始匹配,符号本身不匹配任何字符
re.match(r'^ab','abcdef').group()
Out[5]: 'ab'
- $ 在字符串结束的地方开始匹配,符号本身不匹配任何字符
re.match(r'ab$','ab').group()
Out[8]: 'ab'
re.match(r'a.b$','acb').group()
Out[9]: 'acb'
贪婪与⾮贪婪模式
在重复匹配时,正则表达式默认总是尽可能多的匹配,这被称为贪婪模式。例如,针对⽂本dxxxdxxxd,表达式(d)(\w+)(d)中的\w+将匹配第⼀个d和最后⼀个d之间的所有字符xxxdxxx。可⻅,\w+在匹配的时候,总是尽可能多的匹配符合它规则的字符。同理,带有?、*和{m,n}的重复匹配表达式都是尽可能地多匹配
- 匹配多于需求
re.match(r'<div>.*</div>','<div>abc</div><div>bcd</div>').group() # 匹配<div>abc</div> 贪婪
Out[11]: '<div>abc</div><div>bcd</div>'
- 非贪婪
re.match(r'<div>.*?</div>','<div>abc</div><div>bcd</div>').group() # 匹配<div>abc</div> 非贪婪
Out[12]: '<div>abc</div>'
校验数字的相关表达式:

特殊场景的表达式:

3 正则表达式练习
- 练习一 *
import re
def fn(ptn,lst):
for x in lst:
result = re.match(ptn,x)
if result:
print(x,'匹配成功,','匹配的结果是:',result.group())
else:
print(x,'匹配失败')
ptn = 'ab.'
lst = ['abc1','ab','aba','abbcd','other']
fn(ptn,lst)
结果
abc1 匹配成功, 匹配的结果是: abc
ab 匹配失败
aba 匹配成功, 匹配的结果是: aba
abbcd 匹配成功, 匹配的结果是: abb
other 匹配失败
- 练习二[] 前面的程序一样,省略不写
ptn = 'm[abcd]n'
lst = ['man','mbn','mdn','mon','nba']
fn(ptn,lst)
结果
man 匹配成功, 匹配的结果是: man
mbn 匹配成功, 匹配的结果是: mbn
mdn 匹配成功, 匹配的结果是: mdn
mon 匹配失败
nba 匹配失败
- 练习三 \d \D
ptn = 'py\d'
lst = ['py2','py3','other','pyxxxx']
fn(ptn,lst)
结果
py2 匹配成功, 匹配的结果是: py2
py3 匹配成功, 匹配的结果是: py3
other 匹配失败
pyxxxx 匹配失败
ptn = 'py\D'
lst = ['py2','py3','other','pyxxxx']
fn(ptn,lst)
结果
py2 匹配失败
py3 匹配失败
other 匹配失败
pyxxxx 匹配成功, 匹配的结果是: pyx
- \s \S
ptn = 'hello\sworld'
lst = ['hello world','hellooxxx','helloworld','hello,world']
fn(ptn,lst)
结果
hello world 匹配成功, 匹配的结果是: hello world
hellooxxx 匹配失败
helloworld 匹配失败
hello,world 匹配失败
ptn = 'hello\Sworld'
lst = ['hello world','hellooxxx','helloworld','hello,world']
fn(ptn,lst)
结果
hello world 匹配失败
hellooxxx 匹配失败
helloworld 匹配失败
hello,world 匹配成功, 匹配的结果是: hello,world
- \w \W
ptn = '\w-age'
lst = ['1-age','a-age','#-name','_-age']
fn(ptn,lst)
结果
1-age 匹配成功, 匹配的结果是: 1-age
a-age 匹配成功, 匹配的结果是: a-age
#-name 匹配失败
_-age 匹配成功, 匹配的结果是: _-age
ptn = '\W-age'
lst = ['1-age','a-age','#-age','_-age']
fn(ptn,lst)
结果
1-age 匹配失败
a-age 匹配失败
#-age 匹配成功, 匹配的结果是: #-age
_-age 匹配失败
- *匹配前一个字符 要求 匹配的数据是h大头,a-z 可以是0次也可以是多次
ptn = 'h[a-z]*'
lst = ['hello','abc','xxx','h'] # 匹配的数据是h大头,a-z 可以是0次也可以是多次
fn(ptn,lst)
结果
hello 匹配成功, 匹配的结果是: hello
abc 匹配失败
xxx 匹配失败
h 匹配成功, 匹配的结果是: h
- +
ptn = 'h[a-z]+'
lst = ['hello','abc','xxx','h'] # 匹配的数据是h大头,a-z 可以是0次也可以是多次
fn(ptn,lst)
结果
hello 匹配成功, 匹配的结果是: hello
abc 匹配失败
xxx 匹配失败
h 匹配失败
- 匹配一个数字或字符是6位 用{n}
ptn = '[\w]{6}'
lst = ['hello','python','#^&*?','123456'] # 匹配一个数字或字符是6位
fn(ptn,lst)
结果
hello 匹配失败
python 匹配成功, 匹配的结果是: python
#^&*? 匹配失败
123456 匹配成功, 匹配的结果是: 123456
- 匹配前一个字符至少3次,最多7次
ptn = '[\w]{3,7}'
lst = ['abcd','python','#^&*?','_xxx123','12345678'] # 匹配前一个字符
fn(ptn,lst)
结果
abcd 匹配成功, 匹配的结果是: abcd
python 匹配成功, 匹配的结果是: python
#^&*? 匹配失败
_xxx123 匹配成功, 匹配的结果是: _xxx123
12345678 匹配成功, 匹配的结果是: 1234567
- 匹配2以上的字符或者数字,应该不包括2, 3-无穷
ptn = '[\w]{3,}'
lst = ['ab','python','#^&*?','_xxx123','12345678'] # 匹配2以上的字符或者数字,应该不包括2, 3-无穷
fn(ptn,lst)
结果
ab 匹配失败
python 匹配成功, 匹配的结果是: python
#^&*? 匹配失败
_xxx123 匹配成功, 匹配的结果是: _xxx123
12345678 匹配成功, 匹配的结果是: 12345678
- 匹配一个数字或者字母开头的邮箱 用$匹配字符串结尾 就可以把.cn的去掉
ptn = '[\w]+@qq.com$' # 匹配一个数字或者字母开头的邮箱 用$匹配字符串结尾 就可以把.cn的去掉
lst = ['123@qq.com','abc@yy.com','bcde@qq.com.cn',]
fn(ptn,lst)
结果
123@qq.com 匹配成功, 匹配的结果是: 123@qq.com
abc@yy.com 匹配失败
bcde@qq.com.cn 匹配失败
4 re模块常⽤⽅法

compile(pattern, flags=0)
这个⽅法是re模块的⼯⼚方法,⽤于将字符串形式的正则表达式编译为Pattern模式对象,可以实现更加效率的匹配。第⼆个参数flag是匹配模式 使⽤compile()完成⼀次转换后,再次使⽤该匹配模式的时候就不能进⾏转换了。经过compile()转换的正则表达式对象也能使⽤普通的re⽅法
第二个参数flag匹配模式


import re
ptn = re.compile(r'abc')
ptn.match('abc123').group()
Out[4]: 'abc'
ptn.match('ABC123').group()
Traceback (most recent call last):
File "D:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2910, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-5-ee977d846b7b>", line 1, in <module>
ptn.match('ABC123').group()
AttributeError: 'NoneType' object has no attribute 'group'
然后加入第二个参数 re.I
ptn = re.compile(r'abc',re.I)
ptn.match('ABC123').group()
Out[7]: 'ABC'
search(pattern, string, flags=0)
在⽂本内查找,返回第⼀个匹配到的字符串。它的返回值类型和使⽤⽅法与
match()是⼀样的,唯⼀的区别就是查找的位置不⽤固定在⽂本的开头
re.search(r'abc','123abc567abc789').group()
Out[8]: 'abc'
findall(pattern, string, flags=0)
作为re模块的三⼤搜索函数之⼀,findall()和match()、search()的不同之处在
于,前两者都是单值匹配,找到⼀个就忽略后⾯,直接返回不再查找了。⽽
findall是全⽂查找,它的返回值是⼀个匹配到的字符串的列表。这个列表没有
group()⽅法,没有start、end、span,更不是⼀个匹配对象,**仅仅是个列表!**如果⼀项都没有匹配到那么返回⼀个空列表
re.findall(r'abc','123abc567abc789')
Out[9]: ['abc', 'abc']
re.findall(r'abc','123abc567abc789')[1] # 要第二个数
Out[10]: 'abc'
re.findall(r'ABC','123abc567abc789')
Out[11]: []
re.findall(r'\d{1,}','8+7*5+6/3')
Out[12]: ['8', '7', '5', '6', '3']
等价于
re.findall(r'\d+','8+7*5+6/3')
Out[13]: ['8', '7', '5', '6', '3']
split(pattern, string, maxsplit=0, flags=0)
re模块的split()⽅法和字符串的split()⽅法很相似,都是利⽤特定的字符去分割字符串。但是re模块的split()可以使⽤正则表达式,因此更灵活,更强⼤
re.split(r'[\+\*\/]','8+7*5+6/3')
Out[14]: ['8', '7', '5', '6', '3']
re.split(r'[\+\*\/]','8+7*5+6/3')
Out[14]: ['8', '7', '5', '6', '3']
re.split(r'[\D]+','8+7*5+6/3')
Out[15]: ['8', '7', '5', '6', '3']
re.split(r'[\D]','8+7*5+6/3')
Out[16]: ['8', '7', '5', '6', '3']
re.split(r'\D','8+7*5+6/3')
Out[17]: ['8', '7', '5', '6', '3']
re.split(r'\+\*\/','8+7*5+6/3')
Out[18]: ['8+7*5+6/3']
split有个参数maxsplit,⽤于指定分割的次数
re.split(r'[\D]','8+7*5+6/3',maxsplit=2)
Out[19]: ['8', '7', '5+6/3']
sub(pattern, repl, string, count=0, flags=0)
sub()⽅法类似字符串的replace()⽅法,⽤指定的内容替换匹配到的字符,可以指定替换次数
s = 'i am stonebridge nice to meet you!i like girl'
re.sub(r'i','I',s)
Out[21]: 'I am stonebrIdge nIce to meet you!I lIke gIrl'
5 分组功能
Python的re模块有⼀个分组功能。所谓的分组就是去已经匹配到的内容再筛选出需要的内容,相当于⼆次过滤。实现分组靠圆括号(),⽽获取分组的内容靠的是group()、groups(),其实前⾯我们已经展示过。re模块⾥的积个重要⽅法在分组上,有不同的表现形式,需要区别对待
# 需求是匹配到$88和$55
import re
text = 'apple price is $88,orange is $55'
r = re.search('.+(\$\d+).+(\$\d+)',text)
print(r.group())
结果是
apple price is $88,orange is $55
貌似不对
# 需求是匹配到$88和$55
import re
text = 'apple price is $88,orange is $55'
r = re.search('.+(\$\d+).+(\$\d+)',text)
print(r.group(2))
结果
$55
# 需求是匹配到$88和$55
import re
text = 'apple price is $88,orange is $55'
r = re.search('.+(\$\d+).+(\$\d+)',text)
print(r.group(0))
结果
apple price is $88,orange is $55
# 需求是匹配到$88和$55
import re
text = 'apple price is $88,orange is $55'
r = re.search('.+(\$\d+).+(\$\d+)',text)
# print(r.group(0))
print(r.groups())
结果
('$88', '$55')
- group()和groups()匹配分组, group(1)匹配第一个分组, group(2)第二个分组, groups()匹配所有分组。。。元组
本文详细介绍了Python中的正则表达式,包括概念、应用场景、Python对其的支持,如普通字符、元字符、预定义匹配字符集、重复匹配和位置匹配。还探讨了re模块常用方法,如match()、search()、findall()、split()和sub(),以及正则表达式的分组功能。

2万+

被折叠的 条评论
为什么被折叠?



