前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >在python中使用正则表达式

在python中使用正则表达式

作者头像
冰霜
发布于 2022-03-15 11:11:23
发布于 2022-03-15 11:11:23
71000
代码可运行
举报
运行总次数:0
代码可运行

在python中通过内置的re库来使用正则表达式,它提供了所有正则表达式的功能

一、写在前面:关于转义的问题

正则表达式中用“\”表示转义,而python中也用“\”表示转义,

当遇到特殊字符需要转义时,你要花费心思到底需要几个“\”,

所以为了避免这个情况,墙裂推荐使用原生字符串类型(raw string)来书写正则表达式。

方法很简单,只需要在表达式前面加个“r”即可,如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
r'\d{2}-\d{8}'
r'\bt\w*\b'

二、Re库常用的功能函数

序号 001

re.match()

从字符串的起始位置匹配,匹配成功,返回一个匹配的对象,否则返回None

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
语法:re.match(pattern, string, flags=0)
pattern:匹配的正则表达式
string:要匹配的字符串
flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等;flags=0表示不进行特殊指定

可选标志如下:

修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
不含标志位:
>>> re.match(r'\d{2}','123')
<_sre.SRE_Match object; span=(0, 2), match='12'>
>>> re.match(r'\d{2}','ab123')
>>> print(re.match(r'\d{2}','ab123'))
None

含有标志位:
>>> re.match(r'a','ab123').group()
'a'
>>> re.match(r'a','Ab123').group()
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
re.match(r'a','Ab123').group()
AttributeError: 'NoneType' object has no attribute 'group'
>>> re.match(r'a','Ab123',re.I).group()
'A'

序号 002

re.search()

扫描整个字符串并返回第一个成功的匹配对象,否则返回None

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
语法:re.search(pattern, string, flags=0)

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> re.search(r'\d{2}','Ab123')
<_sre.SRE_Match object; span=(2, 4), match='12'>
>>> re.search(r'\d{2}','Abcde')
>>> print(re.search(r'\d{2}','Abcde'))
None

可以看到match()和search()返回的是match对象(即匹配对象),

可以通过group()方法获得匹配内容

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> re.search(r'\d{2}','Ab12c34d56e78').group()
'12'
>>> re.match(r'\d{2}','12c34d56e78').group(0)
'12'

group() 同group(0)就是匹配正则表达式整体结果,也就是所有匹配到的字符

group()其实更多的结合分组来使用,

即如果在正则表达式中定义了分组

(什么是分组?参见正则表达式学习,一个左括号“(”,表示一个分组),

就可以在match对象上用group()方法提取出子串来。

后面会单独写一下group()和groups()的用法,这里先简单了解一下。

re.match与re.search的区别:

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;

而re.search匹配整个字符串,直到找到一个匹配(注意:仅仅是第一个)

序号 003

re.findall()

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表

注意:match 和 search 是匹配一次,而findall 匹配所有

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> re.findall(r'\d{2}','21c34d56e78')
['21', '34', '56', '78']

序号 004

re.finditer()

和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回.

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> match = re.finditer(r'\d{2}','21c34d56e78')
>>> for t in match:
    print(t.group())
34
78
>>>

序号 005

re.split()

根据正则表达式中的分隔符把字符分割为一个列表并返回成功匹配的列表.

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> match = re.split(r'\.|-','hello-world.data')   # 使用 .- 作为字符串的分隔符
>>> print(match)
['hello', 'world', 'data']

字符串也有split方法,如下,作个对比:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
字符串的split方法
>>> 'a b   c'.split(' ')  # b和c之间有3个空格
['a', 'b', '', '', 'c']

如果用空格不好理解的话,可以换位x
>>> 'axbxxxc'.split('x')
['a', 'b', '', '', 'c']
>>>

可以看到,单纯用字符串的split方法无法识别连续的空格,

用正则表示式如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> re.split(r'\s+', 'a b   c')  # \s+ 表示匹配一个或多个空白符(\s表示匹配空白符,+表示重复1次或1次以上)
['a', 'b', 'c']
>>>

序号 006

re.sub()

用于替换字符串中的匹配项

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
语法: re.sub(pattern, repl, string, count=0)


pattern : 正则中的模式字符串。
repl : 替换的字符串,也可为一个函数。
string : 要被查找替换的原始字符串。
count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> match = re.sub(r'a', 'b','aaccaa')   # 把字符串中的a都替换为b
>>> print(match)
bbccbb
>>>

序号 007

re.compile()

compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,然后就可以用编译后的正则表达式去匹配字符串

语法如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> help(re.compile)
Help on function compile in module re:

compile(pattern, flags=0)
    Compile a regular expression pattern, returning a pattern object.
>>>

pattern : 一个字符串形式的正则表达式 
flags :可选,表示匹配模式,比如忽略大小写,多行模式等

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> test_pattern = re.compile(r'\d{2}')   # 编译一个正则表达式,并将其赋给一个变量
>>> m = test_pattern.match('12bc34')   # 使用编译后的正则表达式对象直接匹配字符串
>>> m
<_sre.SRE_Match object; span=(0, 2), match='12'>

>>> test_pattern = re.compile(r'a\w+')  # 生成一个正则表达式对象(这里是匹配以a开头的单词)
>>> m = test_pattern.findall('apple,blue,alone,shot,attack') # 使用findall()函数匹配所有满足匹配规则的子串
>>> m
['apple', 'alone', 'attack']

序号 008

group()和groups()

一般用match()或search()函数匹配,得到匹配对象后,

需要用group()方法获得匹配内容;

同时也可以提取分组截获的字符串(正则表达式中()用来分组)

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> pattern = re.compile(r'^(\d{3})-(\d{3,8})$')  # 匹配一个3位数开头,然后一个-,然后跟着3-8位数字的字符串
>>> m = pattern.match('020-1234567')
>>> m
<_sre.SRE_Match object; span=(0, 11), match='020-1234567'>
>>> m.group()   #  显示整个匹配到的字符
'020-1234567'
>>> m.group(0)  # 同样是显示整个匹配到的字符
'020-1234567'  
>>> m.group(1)   # 提取第1个分组中的子串
'020'
>>> m.group(2)   # 提取第2个分组中的子串
'1234567'
>>> m.group(3)   # 因为不存在第3个分组,所以这里会报错:没有这样的分组
Traceback (most recent call last):
  File "<pyshell#73>", line 1, in <module>
    m.group(3)
IndexError: no such group
>>> m.groups()
('020', '1234567')
>>>

三、贪婪匹配和非贪婪匹配

贪婪匹配:匹配尽可能多的字符;

非贪婪匹配:匹配尽可能少的字符

python的正则匹配默认是贪婪匹配

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> re.match(r'^(\w+)(\d*)$','abc123').groups()
('abc123', '')
>>> re.match(r'^(\w+?)(\d*)$','abc123').groups()
('abc', '123')

表达式1:
\w+表示匹配字母或数字或下划线或汉字并重复1次或更多次;\d*表示匹配数字并重复0次或更多次。
分组1中(\w)是贪婪匹配,它会在满足分组2(\d*)的情况下匹配尽可能多的字符(有点拗口)因为分组2(\d*)匹配0个数字也满足,所以分组1就把所有字符全部匹配掉了,分组2只能匹配空了。

表达式2:在表达式后加个?即可进行非贪婪匹配,如上面的(\w+?),
因为分组1进行非贪婪匹配,也就是满足分组2匹配的情况下,分组1尽可能少的匹配,
这样的话,上面分组2(\d*)会把所有数字(123)都匹配,所以分组1匹配到(abc)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 冰霜blog 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 从字符串的起始位置匹配,匹配成功,返回一个匹配的对象,否则返回None
  • 可以看到match()和search()返回的是match对象(即匹配对象),
  • 可以通过group()方法获得匹配内容
  • re.match与re.search的区别:
  • re.split()
  • re.sub()
  • re.compile()
  • compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,然后就可以用编译后的正则表达式去匹配字符串
  • group()和groups()
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文