【一】正则
(1)引入
(2)字符组
- 字符组 :[] 在同一个位置可能出现的各种字符组成了一个字符组
- 在正则表达式中用[]表示
- 字符分为很多类
- 假如你现在要求一个位置"只能出现一个数字"
- 那么这个位置上的字符只能是0、1、2...9这10个数之一。
正则 |
待匹配字符 |
匹配结果 |
说明 |
[0123456789] |
8 |
True |
在一个字符组里枚举合法的所有字符,字符组里的任意一个字符和"待匹配字符"相同都视为可以匹配 |
[0123456789] |
a |
False |
由于字符组中没有"a"字符,所以不能匹配 |
[0-9] |
7 |
True |
也可以用-表示范围,[0-9]就和[0123456789]是一个意思 |
[a-z] |
s |
True |
同样的如果要匹配所有的小写字母,直接用[a-z]就可以表示 |
[A-Z] |
B |
True |
[A-Z]就表示所有的大写字母 |
[0-9a-fA-F] |
e |
True |
可以匹配数字,大小写形式的a~f,用来验证十六进制字符 |
(3)元字符
元字符 |
匹配内容 |
. |
匹配除换行符以外的任意字符 |
\w |
匹配字母或数字或下划线 |
\s |
匹配任意的空白符 |
\d |
匹配数字 |
\n |
匹配一个换行符 |
\t |
匹配一个制表符 |
\b |
匹配一个单词的结尾 |
^ |
匹配字符串的开始 |
$ |
匹配字符串的结尾 |
\W |
匹配非字母或数字或下划线 |
\D |
匹配非数字 |
\S |
匹配非空白符 |
a|b |
匹配字符a或字符b |
() |
匹配括号内的表达式,也表示一个组 |
[...] |
匹配字符组中的字符 |
[^...] |
匹配除了字符组中字符的所有字符 |
(4)量词
量词 |
用法说明 |
* |
重复零次或多次 |
+ |
重复一次或多次 |
? |
重复零次或一次 |
{n} |
重复n次 |
{n,} |
重复n次或更多次 |
{n,m} |
重复n到m次 |
(5)位置元字符. ^ $
正则 |
待匹配字符 |
匹配 结果 |
说明 |
钱. |
钱一钱二钱三 |
钱一钱二钱三 |
匹配所有"钱."的字符 |
^钱. |
钱一钱二钱三 |
钱一 |
只从开头匹配"钱." |
`钱. |
正则 |
待匹配字符 |
匹配 结果 |
------ |
------------ |
------------ |
------------------- |
钱. |
钱一钱二钱三 |
钱一钱二钱三 |
匹配所有"钱."的字符 |
^钱. |
钱一钱二钱三 |
钱一 |
只从开头匹配"钱." |
| 钱一钱二钱三 | 钱三 | 只匹配结尾的"钱.$" |
|
|
|
(6)重复匹配\* + ? { }
- 前面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配
正则 |
待匹配字符 |
匹配 结果 |
说明 |
钱.? |
钱大和钱二和钱多多 |
钱大 钱二 钱多 |
?表示重复零次或一次,即只匹配"李"后面一个任意字符 |
钱.* |
钱大和钱二和钱多多 |
钱大和钱二和钱多多 |
*表示重复零次或多次,即匹配"李"后面0或多个任意字符 |
钱.+ |
钱大和钱二和钱多多 |
钱大和钱二和钱多多 |
+表示重复一次或多次,即只匹配"李"后面1个或多个任意字符 |
钱.{1,2} |
钱大和钱二和钱多多 |
钱大和 钱二和 钱多多 |
{1,2}匹配1到2次任意字符 |
(7)字符集[][^]
正则 |
待匹配字符 |
匹配 结果 |
说明 |
钱[大钱二和钱多多]* |
钱大和钱二和钱多多 |
钱大和钱二和钱多多 |
表示匹配"钱"字后面[大钱二和钱多多]的字符任意次 |
钱[^和]* |
钱大和钱二和钱多多 |
钱大 钱二 钱多多 |
表示匹配一个不是"和"的字符任意次 |
[\d] |
123qazwsx233 |
1 2 3 2 3 3 |
表示匹配任意一个数字,匹配到6个结果 |
[\d]+ |
123qazwsx233 |
123 233 |
表示匹配任意个数字,匹配到2个结果 |
(8)分组匹配 ()与 或 |[^]

(9)转义符 \
- 在正则表达式中,有很多有特殊意义的是元字符
- 比如\n和\s等
- 如果要在正则中匹配正常的"\n"而不是"换行符"就需要对""进行转义,变成''。
- 在python中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的,在字符串中\也有特殊的含义,本身还需要转义。
- 所以如果匹配一次"\n",字符串中要写成'\n',那么正则里就要写成"\n",这样就太麻烦了。
- 这个时候就用到了r'\n'这个概念,此时的正则是r'\n'就可以了。
正则 |
待匹配字符 |
匹配 结果 |
说明 |
\n |
\n |
False |
因为在正则表达式中\是有特殊意义的字符,所以要匹配\n本身,用表达式\n无法匹配 |
\n |
\n |
True |
转义\之后变成\,即可匹配 |
"\n" |
'\n' |
True |
如果在python中,字符串中的''也需要转义,所以每一个字符串''又需要转义一次 |
r'\n' |
r'\n' |
True |
在字符串之前加r,让整个字符串不转义 |
(10)贪婪匹配
- 贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配
正则 |
待匹配字符 |
匹配 结果 |
说明 |
<.*> |
<script>...<script> |
<script>...<script> |
默认为贪婪匹配模式,会匹配尽量长的字符串 |
<.*?> |
r'\d' |
<script> <script> |
加上?为将贪婪匹配模式转为非贪婪匹配模式,会匹配尽量短的字符串 |
- 几个常用的非贪婪匹配,Pattern
- *? 重复任意次,但尽可能少重复
- +? 重复1次或更多次,但尽可能少重复
- ?? 重复0次或1次,但尽可能少重复
- {n,m}? 重复n到m次,但尽可能少重复
- {n,}? 重复n次以上,但尽可能少重复
(11)
.
是任意字符
*
是取 0 至 无限长度
?
是非贪婪模式。
- 合在一起就是取尽量少的任意字符,一般不会这么单独写
- 他大多用在:
.*?
就是取前面任意长度的字符,直到一个x出现
【二】re模块常用方法
(1)导入模块
(2)查找结果(findall)
| import re |
| |
| |
| namestr='my name is heart,my age is 18' |
| res = re.findall(pattern=r'\d',string=namestr) |
| print(res) |
(3)编译正则表达式(compile)
re.compile
是 Python 中 re
模块的一个函数,用于将正则表达式的字符串形式编译成一个可重复使用的正则表达式对象。这个对象可以被用于多次的匹配操作,从而提高效率,尤其是在需要多次使用同一模式的情况下。
| import re |
| |
| name_str = 'my name is heart,my age is 18' |
| re_type = re.compile(pattern=r'\w') |
| res_one = re.findall(pattern=re_type,string=name_str) |
| print(res_one) |
(4)查找结果(search)
-
re.search
是 Python 中 re
模块提供的一个函数,用于在字符串中搜索第一个匹配给定正则表达式模式的位置。如果找到匹配项,它返回一个包含匹配信息的 re.Match
对象;如果没有找到匹配项,返回 None
。
-
在例子中,字符串'my name is heart, my age is 18'
中的第一个字符是 'm',而正则表达式模式\w
匹配字母、数字或下划线,因此匹配到了 'm'。所以,res_three
的输出是 'm'。group匹配第一个匹配到的字符。
| import re |
| |
| name_str = 'my name is heart,my age is 18' |
| re_type = re.compile(pattern=r'\w') |
| res_two = re.search(pattern=re_type,string=name_str) |
| res_three = re.search(pattern=re_type,string=name_str).group() |
| print(res_two) |
| print(res_three) |
(5)findall和search的区别
re.findall
和 re.search
是 Python 中 re
模块提供的两个不同的正则表达式匹配函数,它们有以下区别:
- 返回类型:
re.findall
: 返回一个包含所有匹配项的列表。如果没有找到匹配项,返回空列表 []
。
re.search
: 返回第一个匹配项的 re.Match
对象。如果没有找到匹配项,返回 None
。
- 匹配范围:
re.findall
: 在整个字符串中搜索,找到所有匹配项,并将它们以列表的形式返回。
re.search
: 在整个字符串中搜索,找到第一个匹配项就停止搜索,并返回一个 re.Match
对象。
- 使用场景:
re.findall
: 适用于需要找到字符串中所有匹配项的情况,例如提取所有的数字、单词等。
re.search
: 适用于只关心第一个匹配项的情况,或者在整个字符串中找到一个匹配项就足够的情况。
(6)查找结果(match)
re.match
是 Python 中 re
模块提供的一个函数,用于检查一个字符串是否以指定的正则表达式模式开头。如果匹配成功,它返回一个表示匹配的 re.Match
对象;如果匹配失败,则返回 None
。
| import re |
| |
| name_str = 'my name is heart,my age is 18' |
| re_type = re.compile(pattern=r'\w') |
| res_one = re.match(pattern=re_type, string=name_str) |
| res_two = re.match(pattern=re_type, string=name_str).group() |
| print(res_one) |
| print(res_two) |
(7)切割(split)
re.split
是 Python 中 re
模块提供的一个函数,用于根据正则表达式模式将字符串分割成一个列表。它的使用方式类似于字符串的 split
方法,但是可以使用更复杂的分隔符模式。
| import re |
| |
| name_str = 'abcd' |
| res_one = re.split(pattern=r'a',string=name_str) |
| print(res_one) |
(8)指定个数替换(sub)
re.sub
是 Python 中 re
模块提供的一个函数,用于在字符串中搜索正则表达式模式,并将匹配的部分替换为指定的字符串。这个函数允许你通过正则表达式来灵活地搜索和替换字符串中的文本。
| import re |
| |
| name_str = 'age4heart5god6' |
| |
| |
| result = re.sub(pattern='\d', repl='D', string=name_str, count=1) |
| print(result) |
(9)替换全部(subn)
re.subn
是 Python 中 re
模块提供的一个函数,与 re.sub
类似,但它返回一个包含替换次数的元组。这个元组的第一个元素是替换后的新字符串,第二个元素是实际进行替换的次数。
| import re |
| |
| name_str = 'age4heart5god6' |
| |
| |
| result = re.subn(pattern='\d',repl= 'H', string=name_str) |
| print(result) |
(10)匹配结果为迭代器(finditer)
re.finditer
是 Python 中 re
模块提供的一个函数,用于在字符串中搜索所有匹配正则表达式模式的部分。与 re.findall
不同,re.finditer
返回一个迭代器,该迭代器生成所有匹配的 re.Match
对象。
| import re |
| |
| name_str = 'age4heart5god6778' |
| |
| |
| ret = re.finditer(pattern='\d', string=name_str) |
| print(ret) |
| |
| print(next(ret).group()) |
| |
| print(next(ret).group()) |
| |
| print([i.group() for i in ret]) |
| |
【三】正则方法之优先级
(1)findall的优先级查询
| import re |
| |
| res = re.findall(pattern='www.(baidu|bilibili).com', string='www.bilibili.com') |
| |
| print(res) |
(2)split的优先级查询
| import re |
| |
| name_str = 'age4heart5god6' |
| |
| res = re.split(pattern="\d+", string=name_str) |
| print(res) |
| |
| res = re.split(pattern="(\d+)", string=name_str) |
| print(res) |

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通