[ python ] 正则表达式及re模块

正则表达式

正则表达式描述:

    正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个‘规则字符串’,这个‘规则字符串’用来
    表达对字符串的一种过滤逻辑。

  在线测试工具:http://tool.chinaz.com/regex/

  需要明确的是正则表达式只和字符串相关。

  正则表达式基础使用参考:http://tool.chinaz.com/regex/

 

re 模块中常用功能函数

1. compile()

编译正则表达式模式,返回一个对象的模式。(可以把那些常用的正则表达式编译成正则表达式对象,这样可以提高一点效率。)

格式:

1
2
3
re.compile(pattern,flags=0)
pattern: 编译时用的表达式字符串。
flags 编译标志位,用于修改正则表达式的匹配方式

 

实例:

复制代码
import re
s1 = 'have a good day.'
rr = re.compile("\w*oo\w*")
print(rr.findall(s1))   # 查看字符串中包含'oo'的单词

# 执行结果:
# ['good']
re_compile.py
复制代码

 

2. match()

 

描述:
决定RE是否在字符串刚开始的位置匹配。

注意:
    这个方法并不是完全匹配,当pattern结束时,若string还有剩余字符,仍然视为成功。想要完全匹配,可以在表达式末尾加上边界匹配符 '$'
    
格式:

1
re.match(pattern, string, flags=0)

 

实例:

复制代码
import re
s1 = 'runnicegoodrunbetterrun'
# rr = re.match('run', 'nicegoodrun better.run')
r1 = re.match('run', 'runnicegoodrunbetterrun').group()
r2 = re.match('run', 'Runnicegoodrunbetterrun', re.I).group()   # re.I 忽视大小写

print('r1:', r1)
print('r2:', r2)

# 执行结果:
# r1: run
# r2: Run
re_match.py
复制代码

 

 

3. search()

re.search函数会在字符串内查找模式匹配,只要找到第一个匹配然后返回,如果字符串没有匹配,则返回None

1
re.search(pattern, string, flags=0)

 

实例:

复制代码
import re
s1 = 'run nice good run better rungood'
rr = re.search("good", s1).group()    # 只会匹配到一个就直接返回
print(rr)

# 执行结果:
# good
re_search.py
复制代码

 

 

注意:
    match和search一旦匹配成功,就是一个 match object 对象,而match object对象有以下方法:

  •     group()  返回被 RE 匹配的字符串
  •     start()   返回匹配开始的位置
  •     end()      返回匹配结束的位置
  •     span()      返回一个元组包含匹配的位置
  •     group()   返回 re 整体匹配的字符串,可以一次输入多个组号,对应组号匹配的字符串。

 

a.group()    返回re整体匹配的字符串
b.group(n, m)    返回组号为n,m所匹配的字符串,如果组号不存在,则返回indexError异常
c.groups()    groups() 方法返回一个包含正则表达式中所有小组字符串的元组,从 1 到所含的小组号,通常groups()不需要参数,返回一个元组,
元组中的元就是正则表达式中定义的组。   

 

复制代码
import re
a = "123abc456"
rr = re.compile("([0-9]*)([a-z]*)([0-9]*)")
print('group(0):', rr.search(a).group(0))    # group(0) 返回正则匹配到的全部内容
print('group(1):', rr.search(a).group(1))    # group(1) 列出第一个 ([a-z]*) 匹配到的部分
print('group(2):', rr.search(a).group(2))    # group(2) 列出第二个 ([0-9]*) 匹配到的部分
print('group(3):', rr.search(a).group(3))    # group(3) 列出第三个 ([0-9]*) 匹配到的部分
print('groups():', rr.search(a).groups())    # groups() 以元组的形式列出每个括号中匹配到的内容

# 执行结果:
# group(0): 123abc456
# group(1): 123
# group(2): abc
# group(3): 456
# groups(): ('123', 'abc', '456')
re_group.py
复制代码

 

 

4. findall()

描述:
re.findall 遍历匹配,可以获得字符串中所有匹配的字符串,返回一个列表

格式:

1
re.findall(pattern, string, flags=0)

 

实例:

复制代码
import re

p = re.findall("(\d+)", 'asdf12sdf123ad')   # 当匹配到多个值,以列表的形式返回
print(p)

# 执行结果:
# ['12', '123']


import re

tt = 'ggood booyy nice day'
print(re.findall("\w*oo\w*", tt))
print(re.findall("(\w)*oo(\w)", tt))    # 通过小括号分组,得到列表中的元组

# 执行结果:
# ['ggood', 'booyy']
# [('g', 'd'), ('b', 'y')]
re_findall.py
复制代码

 

 

5. finditer()

描述:

搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器。找到RE匹配的所有部分,并把他们作为一个迭代器返回。

 

格式:

re.finditer(pattern, string, flags=0)

 

 

实例:

复制代码
import re

iter = re.finditer('\d+', 'adfasdfq2313sdasf2qe4123')
for i in iter:
    print(i)    # finditer返回的是一个迭代器
    print(i.group())    # 返回一组匹配到的部分
    print(i.span())     # 返回一个元组包含匹配(开始,结束)的位置

# 执行结果:
# <_sre.SRE_Match object; span=(8, 12), match='2313'>
# 2313
# (8, 12)
# <_sre.SRE_Match object; span=(17, 18), match='2'>
# 2
# (17, 18)
# <_sre.SRE_Match object; span=(20, 24), match='4123'>
# 4123
# (20, 24)
re_finditer.py
复制代码

 

 

6. split()

描述:

按照能够匹配的字串将 string 分割后返回列表。
可以使用re.split来分割字符串,如:re.split(r'\s+', text);将字符串按空格分割成一个单词列表。

 

格式:

re.split(pattern, string[, maxsplit])
maxsplit用于指定最大分割次数,不指定将全部分割。

 

 

实例:

复制代码
import re
print(re.split('\d+','one1two2three3four4five5'))

# 执行结果:
# ['one', 'two', 'three', 'four', 'five', '']


re.split 用法在这里要注意下:
    当正则中使用分组和不使用分组返回的是不同的结果:
    
import re
print(re.split('[a-z]','111a222'))
print(re.split('([a-z])','111a222'))

# 执行结果:
# ['111', '222']        # 未使用分组
# ['111', 'a', '222']   # 使用分组
re_split.py
复制代码

 

 

通过上面的例子,我们可以看到未使用分组和使用分组的不同,这里总结一下:

当正则未使用分组(正则未带小括号)时,按照匹配到的部分进行切割,且匹配到的部分不会出现在结果列表中
当正则使用分组(正则带小括号)时,按照匹配到的部分进行切割,匹配到的部分作为元素出现在列表中,且匹配到值的索引按照奇数位出现1、3、5、7...

灵活的使用分组会带来很多的便捷,后面编写计算器的代码中就会用到。

 

7. sub()

使用re替换string中每一个匹配的子串后返回替换后的字符串

格式:

re.sub(pattern, repl, string, count)

默认全部替换

实例:

复制代码
import re
s1 = '1 + 2 + (4 / 5  + 2)'

print(re.sub(' ', '', s1))  # 直接去除计算表达式中的空格

# 执行结果:
# 1+2+(4/5+2)
re_sub.py
复制代码

 

 

8. subn()

 

描述:

返回元组类型,最后一位为替换的次数

格式:

subn(pattern, repl, string, count=0, flags=0)

 

 

实例:

复制代码
import re
s1 = '1 + 2 + (4 / 5  + 2)'

print(re.subn(' ', '', s1))  # 直接去除计算表达式中的空格

# 执行结果:
# ('1+2+(4/5+2)', 9)    # 替换了9次空格
re_subn.py
复制代码

 

 

re模块方法区分

1. re.match与re.search与re.findall的区别:

re.match     只是匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None
re.search     匹配整个字符串,直到直到一个匹配。

复制代码
import re
s1 = 'abc123'
print(re.match("[\d]", s1))     # 从头开始搜索数字,如果开始没有匹配到返回None
print(re.search("[\d]", s1).group())    # 从头开始搜索数字,匹配到第一个直接返回一个迭代器
print(re.findall("[\d]", s1))   # 遍历查找字符串中的数字部分,查找到每个数字都以元素的形式展现

# 执行结果:
# None
# 1
# ['1', '2', '3']
re_match_search.py
复制代码

 

 

2. 贪婪匹配和非贪婪匹配

*?,+?,??,{m,n}?    前面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配

 

实例1:

复制代码
import re
a = re.findall(r"a(\d+?)",'a23b')   # 在正则后面加'?',表示惰性匹配,匹配到一个就直接返回
print(a)
b = re.findall(r"a(\d+)",'a23b')    # 贪婪匹配
print(b)

# 执行结果:
# ['2']
# ['23']
实例1
复制代码

 

实例2:

复制代码
a = re.match('<(.*)>','<H1>title<H1>').group()
print(a)
b = re.match('<(.*?)>','<H1>title<H1>').group()
print(b)

# 执行结果:
# <H1>title<H1>
# <H1>
实例2
复制代码

实例3:

复制代码
a = re.findall(r"a(\d+)b",'a3333b')
print(a)
b = re.findall(r"a(\d+?)b",'a3333b')
print(b)

# 执行结果:
# ['3333']
# ['3333']
实例3
复制代码

 

 

参考链接:
    https://www.cnblogs.com/tina-python/p/5508402.html
    http://tool.chinaz.com/regex/
    http://www.cnblogs.com/Eva-J/articles/7228075.html#_label10

 

本文作者:hukey

本文链接:https://www.cnblogs.com/hukey/p/9778369.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   hukey  阅读(315)  评论(0编辑  收藏  举报
编辑推荐:
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
阅读排行:
· Sdcb Chats 技术博客:数据库 ID 选型的曲折之路 - 从 Guid 到自增 ID,再到
· 语音处理 开源项目 EchoSharp
· 《HelloGitHub》第 106 期
· mysql8.0无备份通过idb文件恢复数据过程、idb文件修复和tablespace id不一致处
· 使用 Dify + LLM 构建精确任务处理应用
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 彩虹 Jay
彩虹 - Jay
00:00 / 00:00
An audio error has occurred.

彩虹 + 轨迹 (Live) - 周杰伦 (Jay Chou)

彩虹

词:周杰伦

曲:周杰伦

哪里有彩虹告诉我

哪里有彩虹告诉我

能不能把我的愿望还给我

能不能把我的愿望还给我

为什么天这么安静

为什么天这么安静

所有的云都跑到我这里

有没有口罩一个给我

有没有口罩一个给我

释怀说了太多就成真不了

释怀说了太多就成真不了

也许时间是一种解药

也许时间是一种解药

也是我现在正服下的毒药

也是我现在正服下的毒药

看不见你的笑 我怎么睡得着

看不见你的笑 我怎么睡得着

你的声音这么近我却抱不到

你的声音这么近我却抱不到

没有地球太阳还是会绕

没有地球太阳还是会绕

没有理由我也能自己走

没有理由我也能自己走

你要离开 我知道很简单

你要离开 我知道很简单

你说依赖 是我们的阻碍

你说依赖 是我们的阻碍

就算放开 但能不能别没收我的爱

就算放开 但能不能别没收我的爱

当作我最后才明白

当作我最后才明白

看不见你的笑 要我怎么睡得着

看不见你的笑 要我怎么睡得着

你的声音这么近我却抱不到

没有地球太阳还是会绕 会绕

没有理由我也能自己走掉

释怀说了太多就成真不了

也许时间是一种解药 解药

也是我现在正服下的毒药

轨迹

词:黄俊郎

曲:周杰伦

我会发着呆然后忘记你

接着紧紧闭上眼

想着哪一天 会有人代替

想着哪一天 会有人代替

让我不再想念你

我会发着呆 然后微微笑

我会发着呆 然后微微笑

接着紧紧闭上眼

又想了一遍 你温柔的脸

又想了一遍 你温柔的脸

在我忘记之前