Python进阶--模块-re
Python进阶–模块-re
1. 正则表达式
正则表达式,在字符串处理业务中经常会用到。这里对正则表达式的匹配规则不再赘述,我们仅介绍Python的re
模块。
2. findall
2.1 方法解析
findall
是re
模块中常用的方法,与其他方法不同的是他的返回值是一个列表。
findall(pattern, string, flags=0):return list()
- findall:正则匹配模型
- string:要匹配的字符串
- flag:匹配模式
2.2 举个栗子
import res = "aAbBcCdD"
f = re.findall(r"[a-z][A-Z][a-z]", s)print(f)['aAb', 'cCd']
观察结果我们不难发现:并没有匹配到bBc,对其分析:
- 匹配时首先匹配到
aAb
并加入返回的列表中 - 继续匹配,此时指针指到字符B(接着匹配,而不重头再来),字符B不符合,不断后移。
- 匹配到字符串
bCc
。
由此得出结论:
匹配成功后,再次匹配时,会从已匹配字符串的后一位开始匹配(并不重新开始)。简言之,已经匹配过的字符串不会参与到后续匹配。
2.3 匹配模式
findall
方法有参数flag表示匹配模式,其含义如下:
re.A 或 re.ASCII | 使用ASCII字符集进行匹配(不常用) |
---|---|
re.I 或 re.IGNORECASE | 忽略大小写匹配 |
re.L 或 re.LOCALE | 使用当前预定字符类 \w \W \b \B \s \S 取决于当前区域设定(不常用) |
re.U 或 re.UNICODE | 使用Unicode字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性(不常用) |
re.M 或 re.MULTILINE | 多行匹配,使"^","$"可以在每一行中都进行匹配 |
re.S 或 re.DOTALL | 使 “.” 可以匹配换行符"\r","\n" |
re.X 或 re.VERBOSE | 去掉正则表达式中的所有空格符(不常用) |
import res = """
name: danny
age: 14
"""
f = re.findall(r": (.*?).age: (.*?)$", s)
f_s = re.findall(r": (.*?).age: (.*?)\b$", s, re.S)
f_n = re.findall(r": (.*?)\nage: (.*?)\b$", s, re.S)print("f: ",f)
print("f_s: ",f_s)
print("f_n: ",f_n)f: []
f_s: [('danny', '14')]
f_n: [('danny', '14')]
首行的danny
和次行的age
之间有换行符\n
,正常模式下元符号.
无法匹配到\n \r
等。但是,使用模式re.S
后,元符号.
可以匹配到\n \r
。
故f
的结果为空,f_s
匹配到字符串,f_n
是对照组。
3.4 分组
3.4.1 简介
什么是组?简单来说当我们想要从符合匹配规则的字符串中提取一段或多段字符串时,这一段段字符串就是一个个组。例如从aAbBcC
中使用r"[a-z][A-Z]"
取出aA
,bB
,cC
,这时我们就说,结果有三个组。
3.4.2 对比
设计对照组如下:
string = "a1b2c3d4"
no_group = r"\w\d"
has_group = r"(\w)\d"
mul_group = r"(\w)(\d)"
nest_group = r"((\w)(\d))"print("无分组:", re.findall(no_group, string))
print("有分组:", re.findall(has_group, string)) #将“组”内信息用圆括号包裹
print("多分组:", re.findall(mul_group, string))
print("嵌套分组:", re.findall(nest_group, string))无分组: ['a1', 'b2', 'c3', 'd4']
有分组: ['a', 'b', 'c', 'd']
多分组: [('a', '1'), ('b', '2'), ('c', '3'), ('d', '4')]
嵌套分组: [('a1', 'a', '1'), ('b2', 'b', '2'), ('c3', 'c', '3'), ('d4', 'd', '4')]
无分组时,从符合的字符串中返回匹配结果,如字符串“a1”。
有分组时,仅返回组内成分(圆括号包含的就是组的范围),如字符串"a"。
多个分组时,将所有组封入元祖,每个元祖代表一个匹配到的字符串的结果(如
('a', '1')
),再与其他结果(如('b', '2')等等
)一同封入列表返回嵌套分组时由外到内,将每个组依序封入元祖。上例中依序将组
((\w)(\d)),(\w),(\d)
再次强调:匹配时先依据匹配规则找到匹配的字符串(如’a1’),再对字符串(“a1”)做分组处理,组依于匹配到的字符串而进行操作。分组其实就是说清楚,告诉机器本山人要的是匹配到的字符串的哪一部分。
3.4.3 打开分组
使用?:
可以打开分组,本方法仅适用于不返回re.Match对象的方法,如findall
string = "a1b2c3d4"
no_group = r"\w\d"
has_group = r"(\w)\d"
open_group = r"(?:\w)\d"print("无分组:", re.findall(no_group, string))
print("有分组:", re.findall(has_group, string))
print("打开分组:", re.findall(open_group, string))无分组: ['a1', 'b2', 'c3', 'd4']
有分组: ['a', 'b', 'c', 'd']
打开分组: ['a1', 'b2', 'c3', 'd4']
3. match
3.1 方法解析
match方法用于从字符串头开始匹配符合规则的子字符串,注意是从头开始
def match(pattern, string, flags=0):return re.Match()
- match方法同样接受匹配模式flag字段。
3.2 举个栗子
s = "hello world hello Python"
r = r"h\w+\s\w+"res = re.match(r, s) #只能匹配到 hello world,因为match方法只从字符串开头开始匹配,不匹配其他位置。
print(res.group()) hello world
- 从起始位置起,开始匹配,匹配到则返回Match对象,反之则返回None
4. search
4.1 方法解析
search,浏览全部字符串,匹配第一符合规则的字符串,浏览整个字符串去匹配第一个,未匹配成功返回None。
def search(pattern, string, flags=0):return re.Match
4.2 举个栗子
s = '''<li class=""><a ka="header-job" href="https://www.zhipin.com/job_detail/">职位</a></li><li class=""><a ka="header_brand" href="https://www.zhipin.com/gongsi/">公司</a></li><li class=""><a ka="header-job" href="https://zhiwei url/">职位</a></li><li class=""><a ka="header_brand" href="https://gongsi url/">公司</a></li>
'''.strip()
r = r'.*?job" href="(.*?)/".*?brand" href="(.*?)/"'
res = re.search(r, s, re.S)
print("未分组:", res.group(0))
print("组1内容:", res.group(1))未分组: <li class=""><a ka="header-job" href="https://zhiwei url/">职位</a></li><li class=""><a ka="header_brand" href="https://gongsi url/"
组1内容: https://zhiwei url
- 只匹配第一符合的字符串,所以后面的
https://zhiwei url
不会匹配。
5. Match对象
5.1 简介
re模块中,方法findall返回的是列表对象,可以索引取值,但方法match和search返回值是re.Match对象 。注:为了方便,我们称之为Match对象,全称为:_sre.SRE_Match。
s = "hello world hello Python"
r = r"h\w+\s\w+"res = re.match(r, s)
print(type(res))
print(dir(res))<class '_sre.SRE_Match'>
['group', 'groupdict', 'groups', 'lastgroup', 'start'......
]
5.2 使用
关于**_sre.SRE_Match**对象(以下简称Match对象)的使用,如下所示:
属性和方法 | 说 明 |
---|---|
Pos | 搜索的开始位置 |
Endpos | 搜索的结束位置 |
String | 搜索的字符串 |
Re | 当前使用的正则表达式的对象 |
Lastindex | 最后匹配的组索引 |
Lastgroup | 最后匹配的组名 |
group(index=0) | 某个分组的匹配结果。如果index等于0,便是匹配整个正则表达式 |
groups() | 所有分组的匹配结果,每个分组的结果组成一个列表返回 |
Groupdict() | 返回组名作为key,每个分组的匹配结果座位value的字典 |
start([group]) | 获取组的开始位置 |
end([group]) | 获取组的结束位置 |
span([group]) | 获取组的开始和结束位置 |
expand(template) | 使用组的匹配结果来替换模板template中的内容,并把替换后的字符串返回 |
1. group
group方法用于分组(圆括号中的内容)
#match.group([group1, ...])
- 如果组中组出的参数0,表示不分组,则返回整个匹配的值。
- 如果组中组出的参数是负数或超出组的最大长度,则给出越界错误。
- 参数可以是两个值,返回元组,元组内包含对应“组”的字符串。
- 未匹配到值的组结果为None。
s = '''<li class=""><a ka="header-job" href="https://www.zhipin.com/job_detail/">职位</a></li><li class=""><a ka="header_brand" href="https://www.zhipin.com/gongsi/">公司</a></li>
'''.strip()
r = r'.*?job" href=(.*?)/".*?brand" href=(.*?)/"'res = re.match(r, s, re.S)
print("未分组:", res.group()) #默认参数为0,即返回所匹配到的字符串,不分组
print("组1内容:", res.group(1))
print("组1,2内容:", res.group(1, 2))未分组: <li class=""><a ka="header-job" href="https://www.zhipin.com/job_detail/">职位</a></li><li class=""><a ka="header_brand" href="https://www.zhipin.com/gongsi/"
组1内容: "https://www.zhipin.com/job_detail
组1,2内容: ('"https://www.zhipin.com/job_detail', '"https://www.zhipin.com/gongsi')
2. groups
方法groups以元祖形式返回所有组。
s = '''<li class=""><a ka="header-job" href="https://www.zhipin.com/job_detail/">职位</a></li><li class=""><a ka="header_brand" href="https://www.zhipin.com/gongsi/">公司</a></li>
'''.strip()
r = r'.*?job" href=(.*?)/".*?brand" href=(.*?)/"'res = re.match(r, s, re.S)
print("所有组:", res.groups())所有组: ('https://www.zhipin.com/job_detail', 'https://www.zhipin.com/gongsi')
3. groupdict
方法groupdict返回命名过的组,未命名的不管。
s = '''<li class=""><a ka="header-job" href="https://www.zhipin.com/job_detail/">职位</a></li><li class=""><a ka="header_brand" href="https://www.zhipin.com/gongsi/">公司</a></li>
'''.strip()
r = r'.*?job" href="(?P<zhiwei>.*?)/".*?brand" href="(.*?)/"' #组1命名为zhiwei返回,组2未命名不返回res = re.match(r, s, re.S)
print("命名组:", res.groupdict())命名组: {'zhiwei': 'https://www.zhipin.com/job_detail'}
- 命名通过
?P<name>
完成 - 只返回命名过的
4. start & end
方法start返回对应组的起始字符在初始字符串string中的位置。
方法start返回对应组的结束字符在初始字符串string中的位置。
def start(group=0):return start_indexdef end(group=0):return end_index
- group:组的编号
s = '''<li class=""><a ka="header-job" href="https://www.zhipin.com/job_detail/">职位</a></li><li class=""><a ka="header_brand" href="https://www.zhipin.com/gongsi/">公司</a></li>
'''.strip()
r = r'.*?job" href="(?P<zhiwei>.*?)/".*?brand" href="(.*?)/"' #组1命名为zhiwei返回,组2未命名不返回res = re.match(r, s, re.S)
print("组1开始位置:", res.start(1))
print("组2结束位置:", res.end(2))
print("结束位字符:", s[163])组1开始位置: 38
组2结束位置: 163
结束位字符: /
- 方法end返回的结束位字符索引值是真实索引值+1
5. span
方法span返回组的起始位置和结束位置构成的元祖,即该组的索引范围。
s = '''<li class=""><a ka="header-job" href="https://www.zhipin.com/job_detail/">职位</a></li><li class=""><a ka="header_brand" href="https://www.zhipin.com/gongsi/">公司</a></li>
'''.strip()
r = r'.*?job" href="(?P<zhiwei>.*?)/".*?brand" href="(.*?)/"' #组1命名为zhiwei返回,组2未命名不返回res = re.match(r, s, re.S)
print("组1索引范围:", res.span(1))
print("索引范围对应的字符串:", eval("s[{0}:{1}]".format(*res.span(1)))) #取出该范围的字符串,等价于r[38:71]
print("组1内容:", res.group(1))组1索引范围: (38, 71)
索引范围对应的字符串: https://www.zhipin.com/job_detail
组1内容: https://www.zhipin.com/job_detail
- 方法span返回的索引范围可直接用于提取字符串,即结束位置(71)其实是末尾字符(“l”)的索引值+1。其实返回的是(res.start(1), res.end(1))
6 expand
方法expand作用:在参数字符串中,将特定内容替换为组的内容,类似于字符串格式化。
s = '''<li class=""><a ka="header-job" href="https://www.zhipin.com/job_detail/">职位</a></li><li class=""><a ka="header_brand" href="https://www.zhipin.com/gongsi/">公司</a></li>
'''.strip()
r = r'.*?job" href="(?P<zhiwei>.*?)/".*?brand" href="(.*?)/"' #组1命名为zhiwei返回,组2未命名不返回res = re.match(r, s, re.S)
str_expand = r""" 公司:\2; #\2 会被替换为组2内容公司:\g<2> #\g<2> 会被替换为组2内容职位:\g<zhiwei> #\g<zhiwei> 会被替换为组名为 zhiwei 的组的内容"""
print("expand替换结果:", res.expand(str_expand))expand替换结果: 公司:https://www.zhipin.com/gongsi;公司:https://www.zhipin.com/gongsi职位:https://www.zhipin.com/job_detail
- 替换标志:
\组编号
,\g<组编号>
,\g<组名>
Python进阶--模块-re相关推荐
- Python进阶-正则表达式
Python进阶系列 Python进阶-网络编程-01 Python进阶-网络编程-02 Python进阶-网络编程-03 Python进阶-多任务编程-01 Python进阶-多任务编程-02 Py ...
- 7.1.3 Python进阶 《函数》定义、调用,参数,返回值《面向对象》概念,类,实例,对象,属性,方法《模块、包》导入,自定义,常用内置:datatime,time,random,os,sys
目录 ======== 第四部分 Python进阶 ======== 第一节 函数 4.1.1 函数定义及调用 4.1.2 函数的参数 4.1.3 函数的返回值 第二节 面向对象 4.2.1 面向对象 ...
- Python进阶----pymysql模块的使用,单表查询
Python进阶----pymysql模块的使用,单表查询 一丶使用pymysql 1.下载pymysql包: pip3 install pymysql 2.编写代码 ...
- Python 进阶_模块 包
目录 文章目录 目录 模块的搜索路径和路径搜索 命名空间和变量作用域的比较 变量名的查找/覆盖 导入模块 import 语句 from-import 语句 扩展的 import 语句 as 自动载入模 ...
- Python 进阶_模块 amp; 包
目录 目录 模块的搜索路径和路径搜索 搜索路径 命名空间和变量作用域的比较 变量名的查找覆盖 导入模块 import 语句 from-import 语句 扩展的 import 语句 as 自动载入模块 ...
- Python自学路线图之Python进阶
Python自学路线图的第二个阶段是Python进阶学习,自学完后需要掌握的Python技能: 1.自学Linux操作系统,熟练使用Linux操作系统: 自学网络编程,掌握网络编程相关技术, 能够实现 ...
- Python进阶6——序列操作
1.序列的拼接和复制 Python中使用+对序列进行拼接,使用*对序列进行复制 s=str(1234) l=list(range(2,13)) print(s,l) print('---------- ...
- Python 进阶之路 (九) 再立Flag, 社区最全的itertools深度解析(上)
前言 大家好,今天想和大家分享一下我的itertools学习体验及心得,itertools是一个Python的自带库,内含多种非常实用的方法,我简单学习了一下,发现可以大大提升工作效率,在sf社区内没 ...
- 三步解决C语言中struct字节对齐问题,Python进阶篇-struct字节对齐问题
Python进阶篇-struct字节对齐问题 Python进阶篇-struct字节对齐问题 Python调用C的时候,会传递一些复杂的数据结构,例如结构体,这时候就会遇到各种各样字节对齐的问题.下边所 ...
最新文章
- 1行代码搞定Latex公式编写,这个4.6M的Python小插件,堪称论文必备神器
- 9.7号Linux学习笔记
- js jquery 函数回调
- Mysql基础知识:索引
- C和C++编程中static关键字的含义-修饰函数和变量
- 你好,未来! | 2018腾讯“云+未来”峰会五月启幕
- Jsrender初体验
- css中的外边距合并时垂直方向上的普通流相邻元素间
- 简聊初步尝试服务端渲染的一些感想
- 机房服务器硬件供应,机房服务器硬件维护方法大全
- BP神经网络 MATLAB源程序
- matlab投资组合权重,【原创】投资组合风险-收益关系的Matlab实现
- python求平方根的代码_python求平方根的方法
- nordic 52832 键盘
- Contest3115 - 2021级新生个人训练赛第23场_问题 H: 家庭作业
- C语言入门知识1(零基础新手适用)
- 欺骗的艺术----(8)
- dex2oat对应用启动性能的影响
- 用C语言实现my_strncat
- Ubuntu如何安装pacman