最全的python re正则使用范例,有这一篇足够了
一、什么是正则:
1、正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配
2、re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。
总结一下,先整体了解re正则:
- pattern = re.compile("\d") 将正则表达式编译成一个Pattern规则对象
- pattern.match() 从开始位置开始往后查找,返回第一个符合规则的对象
- pattern.search() 从任何位置开始往后查找,返回第一个符合规则的对象
- pattern.findall() 所有的全部匹配,返回列表
- pattern.finditer() 所有的全部匹配,返回的是一个迭代器
- pattern.split() 分割字符串,返回列表
- pattern.sub() 替换
二、re模块
2.1match方法
2.1.1语法:pattern.match(str, start, end)
实例:
import re #导入re模块
pattern = re.compile(r'\d+') #此处加r表示不转义字符串
m = pattern.match('aaaa123bbb456')
m2 = pattern.match('aaaa123bbb456', 4,10)
print(m) # None
print(m2.group()) # 123
match在没有匹配到数据的时候返回的是 None
match匹配到数据后返回的是一个对象
2.1.2match分组匹配
import re
pattern = re.compile(r'([a-z]+) ([a-z]+)', re.I)
m = pattern.match('hello world Hello Python')
print(m.group()) # hello world
print(m.group(0)) # hello world
print(m.group(1)) # hello
print(m.group(2)) # world
三. re中的编译函数
3.1 compile方法
那么如果一个正则表达式要重复使用几千次,出于效率的考虑,我们是不是应该先把这个正则先预编译好,接下来重复使用时就不再需要编译这个步骤了,直接匹配,提高我们的效率
import re
re_telephone = re.compile(r'^(\d{3})-(\d{3,8})$') # 编译
A = re_telephone.match('010-12345').groups() # 使用
print(A) # 结果 ('010', '12345')
B = re_telephone.match('010-8086').groups() # 使用
print(B) # 结果 ('010', '8086')
编译后生成Regular Expression对象,由于该对象自己包含了正则表达式,所以调用对应的方法时不用给出正则字符串。
3.2 search方法
re.search()方法扫描整个字符串,并返回第一个成功的匹配。如果匹配失败,则返回None。
与re.match()方法不同,re.match()方法要求必须从字符串的开头进行匹配,如果字符串的开头不匹配,整个匹配就失败了;
re.search()并不要求必须从字符串的开头进行匹配,也就是说,正则表达式可以是字符串的一部分
语法:re.search(pattern, string, flags=0)
- pattern : 正则中的模式字符串。
- string : 要被查找替换的原始字符串。
- flags : 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
例1:
import re
content = 'Hello 123456789 Word_This is just a test 666 Test'
result = re.search('(\d+).*?(\d+).*', content)
print(result)
print(result.group()) # print(result.group(0)) 同样效果字符串
print(result.groups())
print(result.group(1))
运行结果:
<_sre.SRE_Match object; span=(6, 49), match='123456789 Word_This is just a test 666 Test'>
123456789 Word_This is just a test 666 Test
('123456789', '666')
123456789
666
Process finished with exit code 0
例2:只匹配数字
import re
content = 'Hello 123456789 Word_This is just a test 666 Test'
result = re.search('(\d+)', content)
print(result)
print(result.group()) # print(result.group(0)) 同样效果字符串
print(result.groups())
运行结果:
<_sre.SRE_Match object; span=(6, 15), match='123456789'>
123456789
('123456789',)
123456789
Process finished with exit code 0
3.3 finall方法
返回一个包含所有匹配到的字符串的列表。
- pattern 匹配模式,由 re.compile 获得
- string 需要匹配的字符串
import re
str = 'say hello world! hello python'
pattern = re.compile(r'(?P<first>h\w)(?P<symbol>l+)(?P<last>o\s)') # 分组,0 组是整个 world!, 1组 or,2组 ld!
match = re.findall(pattern, str)
print(match)
运行结果:
[('he', 'll', 'o '), ('he', 'll', 'o ')]
另外,多讲两个名字类似的:
re.finditer :re.finditer(pattern, string[, flags=0])
re.findall:re.findall(pattern, string[, flags=0])
- pattern compile 生成的正则表达式对象,或者自定义也可
- string 要匹配的字符串
findall 返回一个包含所有匹配到的字符的列表,列表类以元组的形式存在。
finditer 返回一个可迭代对象。
例1:
pattern = re.compile(r'\d+@\w+.com') #通过 re.compile 获得一个正则表达式对象
result_finditer = re.finditer(pattern, content)
print(type(result_finditer))
print(result_finditer) # finditer 得到的结果是个可迭代对象
for i in result_finditer: # i 本身也是可迭代对象,所以下面要使用 i.group()
print(i.group())
result_findall = re.findall(pattern, content)
print(type(result_findall)) # findall 得到的是一个列表
print(result_findall)
for p in result_finditer:
print(p)
运行结果:
<class 'callable_iterator'>
<callable_iterator object at 0x10545ec88>
123456@163.com
234567@163.com
345678@163.com
<class 'list'>
['123456@163.com', '234567@163.com', '345678@163.com']
由结果可知:finditer 得到的是可迭代对象,finfdall 得到的是一个列表
例2:
import re
content = '''email:123456@163.com
email:234567@163.com
email:345678@163.com
'''
pattern = re.compile(r'(?P<number>\d+)@(?P<mail_type>\w+).com')
result_finditer = re.finditer(pattern, content)
print(type(result_finditer))
print(result_finditer)
iter_dict = {} # 把最后得到的结果
for i in result_finditer:
print('邮箱号码是:', i.group(1),'邮箱类型是:',i.group(2))
number = i.group(1)
mail_type = i.group(2)
iter_dict.setdefault(number, mail_type) # 使用 dict.setdefault 创建了一个字典
print(iter_dict)
print('+++++++++++++++++++++++++++++++')
result_findall = re.findall(pattern, content)
print(result_findall)
print(type(result_findall))
运行结果:
<class 'callable_iterator'>
<callable_iterator object at 0x104c5cbe0>
邮箱号码是: 123456 邮箱类型是: 163
邮箱号码是: 234567 邮箱类型是: 163
邮箱号码是: 345678 邮箱类型是: 163
{'123456': '163', '234567': '163', '345678': '163'}
+++++++++++++++++++++++++++++++
[('123456', '163'), ('234567', '163'), ('345678', '163')]
<class 'list'>
finditer 得到的可迭代对象 i,也可以使用 lastindex,lastgroup 方法。
print('lastgroup 最后一个被捕获的分组的名字',i.lastgroup)
findall 当正则没有分组,返回就是正则匹配。
e.findall(r"\d+@\w+.com", content)
['2345678@163.com', '2345678@163.com', '345678@163.com']
有一个分组返回的是分组的匹配
re.findall(r"(\d+)@\w+.com", content)
['2345678', '2345678', '345678']
多个分组时,将结果作为 元组,一并存入到 列表中。
re.findall(r"(\d+)@(\w+).com", content)
[('2345678', '163'), ('2345678', '163'), ('345678', '163')]
小结:search找到就返回,finall全部找到才返回
3.5 split方法
split能够按照所能匹配的字串将字符串进行切分,返回切分后的字符串列表
语法:re.split(pattern, string[, maxsplit=0, flags=0])
pattern:匹配的字符串
string:需要切分的字符串
maxsplit:分隔次数,默认为0(即不限次数)
flags:标志位,用于控制正则表达式的匹配方式,比如:是否区分大小写
import re
line = 'aaa bbb ccc;ddd eee,fff'
print(line)
'aaa bbb ccc;ddd eee,fff'
单字符切割
re.split(r';',line)
结果:
['aaa bbb ccc', 'ddd\teee,fff']
两个字符以上切割需要放在 [ ] 中
re.split(r'[;,]',line)
结果:
['aaa bbb ccc', 'ddd\teee', 'fff']
所有空白字符切割
re.split(r'([;])',line)
结果:
['aaa bbb ccc', ';', 'ddd\teee,fff']
不想保留分隔符,以(?:...)的形式指定
re.split(r'(?:[;])',line)
结果:
['aaa bbb ccc', 'ddd\teee,fff']
四. 贪婪模式与非贪婪模式
正则表达式通常用于在文本中查找匹配的字符串。
Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;
非贪婪则相反,总是尝试匹配尽可能少的字符。在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪
总结一下:
- 贪婪:在满足条件情况下尽可能匹配到数据
- 非贪婪:满足条件就可以,在
"*","?","+","{m,n}"
后面加上?
,就能将贪婪变成非贪婪.
import re
# 贪婪匹配
greedy_pattern = re.compile(r'ab.*c')
greedy_match = greedy_pattern.match('abcaxc')
print("贪婪匹配结果:" + greedy_match.group())
# 非贪婪匹配
not_greedy_pattern = re.compile(r'ab.*?c')
not_greedy_match = not_greedy_pattern.match('abcaxc')
print("非贪婪匹配结果:" + not_greedy_match.group())
输出:
贪婪匹配结果:abcaxc
非贪婪匹配结果:abc

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Linux入门必备|搭建JAVAEE开发环境
2 --> 搭建JAVAEE开发环境 安装JDK 第一步:先将软件通过xftp5 上传到/opt 下 第二步:解压缩到/opt目录下 第三步:配置环境变量的配置文件vim /etc/profile JAVA_HOME=/opt/jdk1.7.0_79 PATH=$JAVA_HOME/bin:$PATH CLASSPATH=$JAVA_HOME/lib:. export JAVA_HOME PATH CLASSPATH 第四步:使配置文件生效 第五步:测试安装成功 第六步:在目录/home/zhangsan下编写HelloWorld.java编译并运行 安装Tomcat 第一步:先将软件通过xftp5 上传到/opt 下 第二步:解压到/opt 第三步:启动tomcat 第四步:Linux上访问tomcat 第五步:windows上访问tomcat 注意:从其它机器上访问需要关闭linux的防火墙。 安装mysql 第一步:查看是否已经安装了mariadb 检查linux是否安装了mariadb数据库,mariadb数据库是mysql的分支。是免费开源的。mariadb和msyql会有...
-
下一篇
Spring Boot 2.5.2 发布,MateCloud 同步升级
一、发布说明 于美国时间6月24日发布Spring Boot 2.5.2版本,此版本包括53 个错误修复、文档改进和依赖项升级。 二、更新内容 2.1 bug修复 在没有类加载器的情况下调用实例化器#27074 EnvironmentPostProcessors 未使用正确的 ClassLoader 进行实例化#27073 EnvironmentPostProcessors 未使用正确的 ClassLoader 进行实例化#27072 实例化器在没有类加载器的情况下被调用#27071 将不存在的类的名称绑定到 Class<?> 属性时失败并不是很有帮助#27061 将不存在的类的名称绑定到 Class<?> 属性时失败并不是很有帮助#27060 无法排除对重新打包战争的依赖#27057 无法排除对重新打包战争的依赖#27056 当应用程序上下文关闭时死锁,然后在应用程序上下文刷新期间调用 System.exit(int) #27049 NettyProperties.leakDetection 的默认值与 Netty 的默认值不一致 #27046 处理“spri...
相关文章
文章评论
共有0条评论来说两句吧...