PYTHON基础知识学习笔记(十)

本文深入解析正则表达式的语法与应用场景,涵盖数据验证、文本提取等核心功能,并通过Python实例展示如何高效处理字符串,包括查找、替换和分割。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

正则表达式

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。

概述

典型使用场景

1、数据验证;
2、文本扫描;
3、文本提取;
4、文本替换;
5、文本分割;
······

语法

正则表达式由字符串构成,其中分为两类:字面值、元字符。
字面值:字面值又包括普通字符,可直接表达原义,(如字母c)。还包括转义字符,需要在前面加“\”才能表达原义,(如^,$,|,?,*,+,(),[],{}等)。

匹配

1、单字,预定义元字符
(1). :除\n外所有的字符;
(2)\d :数字,等同于[0-9];
(3)\D :非数字;
(4)\s :空白字符,等同于\t\n\r\f\v;
(5)\S :非空白字符;
(6)\w :字母数字字符,等同于[a-zA-Z0-9];
(7)\W :非字母数字字符;

2、批量备选
用“|”表示,如取yes或no都可以,可表示为yes|no。

3、量词(字符、元字符、字符集如何重复)
(1)? :出现0次或1次;
(2)* :出现0次或多次;
(3)+ :出现1次或多次;
(4){n,m} :出现次数的范围;
(5){n} :出现n次;
(6){n,} :出现至少n次;
(7){,m} :出现最多m次。

4、贪婪与非贪婪
贪婪(默认):尽量匹配最大范围结果;
非贪婪:尽量匹配最小范围结果,方法是在量词后加“?”。
例:查找之间的内容
在这里插入图片描述
默认贪婪模式
在这里插入图片描述
匹配结果
在这里插入图片描述
非贪婪模式
在这里插入图片描述
匹配结果
在这里插入图片描述

5、边界匹配
(1)^ :行首;
(2)$ :行尾;
(3)\b :单词边界;
(4)\B :非单词边界;
(5)\A :输入开头;
(6)\Z :输入结尾。
:或因上下文差异有不同表现。

python中的正则表达式

RegexObject正则对象(re模块 )

re 模块使 Python 语言拥有全部的正则表达式功能。
例:从文本中查找年龄
不进行编译,直接查找

>>> import re
>>> text = "Tom is 8 years old. Mike is 25 years old."
>>> re.findall('\d+',text)
['8', '25']

编译为字节码后查找,适合多次使用

>>> import re
>>> text = "Tom is 8 years old. Mike is 25 years old."
>>> pattern = re.compile('\d+')
>>> pattern.findall(text)
['8', '25']

1、编译
re.compile(‘模式’)
通常在模式前加r,表示不需要转义:(r’模式’)
例:当\为需要查找的文本时,直接编译会将\当作转义符处理

>>> s = "\\author:Tom"
>>> pattern = re.compile('\\author')
>>> pattern.findall(s)
#运行结果
[]

可以通过在每个\前面再加一个\来处理,比较麻烦

>>> pattern = re.compile('\\\\author')
>>> pattern.findall(s)
#运行结果
['\\author']

也可以通过r表示不需要转义

>>> pattern = re.compile(r'\\author')
>>> pattern.findall(s)
#运行结果
['\\author']

2、查找
.findall()
查找所有非重叠匹配项,返回list。

>>> text = "Tom is 8 years old. Mike is 25 years old."
>>> p_age = re.compile(r'\d+')
>>> p_age.findall(text)
#运行结果
['8', '25']
>>> p_name = re.compile(r'[A-Z]\w+')
>>> p_name.findall(text)
#运行结果
['Tom', 'Mike']

3、.match函数
.match(string[,pos[,endpos]])
从字符串的起始位置匹配一个模式,返回MatchObject,如果起始位置匹配不成功的话,match()就返回none。

>>> import re
>>> text = '<html><head></head><body></body></html>'
>>> pattern = re.compile(r'<html>')
>>> pattern.match(text)
#运行结果
<re.Match object; span=(0, 6), match='<html>'>
>>> type(pattern.match(text))
#运行结果
re.Match

当起始位置为空格,匹配不成功

>>> text2 = ' <html><head></head><body></body></html>'
>>> pattern.match(text2)
#无运行结果
#可指定开始匹配的位置
>>> pattern.match(text2,1)
<re.Match object; span=(1, 7), match='<html>'>

4、.search函数
.search(string[,pos[,endpos]])
.search 可以任意位置搜索,返回MatchObject。

>>> text2 = ' <html><head></head><body></body></html>'
>>> pattern = re.compile(r'<html>')
>>> pattern.match(text2)
#无运行结果
>>> pattern.search(text2)
#运行结果
<re.Match object; span=(1, 7), match='<html>'>

5、.finditer()函数
查找所有非重叠匹配项,返回包含MatchObject元素的迭代器。

>>> text = "Tom is 8 years old. Mike is 25 years old."
>>> p1 = re.compile(r'\d+')
>>> p1.findall(text)
#运行结果,返回一个列表
['8', '25']
>>> p1.finditer(text)
#运行结果,返回一个包含MatchObject元素的迭代器
<callable_iterator at 0x27ee2792b48>

.finditer()函数返回结果可进行迭代

>>> it = p1.finditer(text)
>>> for m in it:
...:    print(m)
...:    
#运行结果
<re.Match object; span=(7, 8), match='8'>
<re.Match object; span=(28, 30), match='25'>

MatchObject匹配对象

主要功能为表现被匹配模式的详细信息。
例:利用re.search函数返回一个MatchObject对象

>>> import re
>>> text = "Tom is 8 years old. Mike is 25 years old."
>>> pattern = re.compile(r'(\d+).*?(\d+)') #括号代表分组,详见下节
>>> m = pattern.search(text)
>>> m
#运行结果
<re.Match object; span=(7, 30), match='8 years old. Mike is 25'>

1、.group()函数
.group()函数返回匹配的字符串
参数为0或空时返回整个匹配

>>> m.group()
#运行结果
'8 years old. Mike is 25'
>>> m.group(0)
#运行结果
'8 years old. Mike is 25'

通过指定参数可以返回特定分组匹配细节

>>> m.group(1)
#运行结果
'8'
>>> m.group(2)
#运行结果
'25'

2..groups()函数
.groups()函数返回包含所有子分组的元组

>>> m.groups()
#运行结果
('8', '25')

3、.start()函数
.start()函数返回特定分组的起始索引

>>> m.start(1)
#运行结果
7
>>> m.start(2)
#运行结果
28

4、.end()函数
.end()函数返回特定分组的终止索引

>>> m.end(1)
#运行结果
8
>>> m.end(2)
#运行结果
30

5..span()函数
.span()函数返回特定分组的起止索引元组

>>> m.span()
#运行结果
(7, 30)

Group编组

使用场景
1、从匹配模式中提取信息。
2、创建子正则以应用量词。
例:想要查找以c结尾,前面重复若干次ab的信息

>>> import re
>>> re.search(r'ab+c','ababc')     #不分组,默认重复的是b
#运行结果
<re.Match object; span=(2, 5), match='abc'>
>>> re.search(r'(ab)+c','ababc')   #分组后,则认为重复的是ab
#运行结果
<re.Match object; span=(0, 5), match='ababc'>

3、限制备选项范围。
例:center与centre写法都正确,需要在查找时两个词都能匹配上
不加分组时默认Center与re均为备选

>>> re.search(r'Center|re','Center')
#运行结果
<re.Match object; span=(0, 6), match='Center'>
>>> re.search(r'Center|re','Centre')
#运行结果
<re.Match object; span=(4, 6), match='re'>

加分组时默认er与re为备选

>>> re.search(r'Cent(er|re)','Center')
#运行结果
<re.Match object; span=(0, 6), match='Center'>
>>> re.search(r'Cent(er|re)','Centre')
#运行结果
<re.Match object; span=(0, 6), match='Centre'>

4、重用正则模式中提取的内容。
若在定义模式时想重用前面的编组,可用\加序号代替,序号从1开始

>>> re.search(r'(\w+)\1','hello hello world')
#运行结果
<re.Match object; span=(2, 4), match='ll'>

声明及引用
声明时直接用圆括号(模式)进行编组,当编组较多时,可以对其分别命名(?P模式)。
引用时可直接使用.group(序号),若已经命名,可使用.group(‘name’)。在模式内可用(?P=name),在表现内可用\g。
直接声明及引用

>>> import re
>>> text = "Tom:98"
>>> pattern = re.compile(r'(\w+):(\d+)')   #直接分组,未命名
>>> m = pattern.search(text)
>>> m.group()
#运行结果
'Tom:98'
>>> m.group(1)     #通过序号引用
#运行结果
'Tom'

声明时命名及引用

>>> pattern = re.compile(r'(?P<name>\w+):(?P<score>\d+)')
>>> m = pattern.search(text)
>>> m.group()
#运行结果
'Tom:98'
>>> m.group(1)      #仍然可以通过序号引用
#运行结果
'Tom'
>>> m.group('name')  #还可以通过名称引用
#运行结果
'Tom'
>>> m.group('score')
#运行结果
'98'

python正则的应用

字符串操作
1、分割字符串
.split(string, maxsplit=0)

>>> import re
>>> text = 'Beautiful is better than ugly.\nExplicit is better than implicit.\nSimple is better than complex.'
#1、先编译再切分
>>> p = re.compile(r'\n')
>>> p.split(text)
#运行结果 
['Beautiful is better than ugly.',
 'Explicit is better than implicit.',
 'Simple is better than complex.']
#2、直接切分
>>> re.split(r'\n',text)
#运行结果
['Beautiful is better than ugly.',
 'Explicit is better than implicit.',
 'Simple is better than complex.']

若希望将分隔字符也打印出来,需要用括号将分隔字符括起来

>>> re.split(r'(\n)',text)
#运行结果
['Beautiful is better than ugly.',
 '\n',
 'Explicit is better than implicit.',
 '\n',
 'Simple is better than complex.']

可以指定按顺序切割出几部分

>>> re.split(r'\n',text,1)
#运行结果
['Beautiful is better than ugly.',
 'Explicit is better than implicit.\nSimple is better than complex.']

2、替换字符串
.sub(repl, string, count=0)
例:将数字替换成-

>>> ords = 'ORD000\nORD001\nORD003'
>>> re.sub(r'\d+','-',ords)
#运行结果
'ORD-\nORD-\nORD-'

将单词两端的*替换成

>>> text = 'Beautiful is *better* than ugly.'
>>> re.sub(r'\*(.*?)\*','<strong></strong>',text) #这样会造成信息丢失
#运行结果
'Beautiful is <strong></strong> than ugly.'       
>>> re.sub(r'\*(.*?)\*','<strong>\g<1></strong>',text) #可在表现中通过序号对分组重用
#运行结果
'Beautiful is <strong>better</strong> than ugly.'
>>> re.sub(r'\*(?P<html>.*?)\*','<strong>\g<html></strong>',text)#也可在表现中通过命名对分组重用
#运行结果
'Beautiful is <strong>better</strong> than ugly.'

该函数也可以改变字符串格式

>>> ords = 'ORD000\nORD001\nORD003'
>>> re.sub(r'([A-Z]+)(\d+)','\g<2>-\g<1>',ords)
#运行结果
'000-ORD\n001-ORD\n003-ORD'

3、替换并返回替换数量
.subn(repl, string, count=0)

>>> re.subn(r'([A-Z]+)(\d+)','\g<2>-\g<1>',ords)
#运行结果
('000-ORD\n001-ORD\n003-ORD', 3)

编译标记
改变正则的默认行为。
1、re.I 忽略大小写

>>> import re
>>> text = 'Python python PYTHON'
>>> re.findall(r'python',text)
#运行结果
['python']
>>> re.findall(r'python',text,re.I)
#运行结果
['Python', 'python', 'PYTHON']

2、re.M 匹配多行

>>> re.findall(r'^<html>','\n<html>')
#运行结果
[]
>>> re.findall(r'^<html>','\n<html>',re.M)
#运行结果
['<html>']

3、re.S 指定“.”匹配所有字符,包括“\n”

>>> re.findall(r'\d(.)','1\ne')
#运行结果
[]
>>> re.findall(r'\d(.)','1\ne',re.S)
#运行结果
['\n']

模块级别操作
1、清理正则缓存
re.purge()
2、逃逸字符
re.escape()
忽略字符原有意义

>>> re.findall(r'^','^python^')
#运行结果
['']
>>> re.findall(re.escape('^'),'^python^')
#运行结果
['^', '^']

未完待续!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值