栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

六、python正则表达式

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

六、python正则表达式

python正则表达式
  • 1.正则表达式的特点和优势
    • 1.1 独立性
    • 1.2 优势
  • 2.正则搜索方法
    • 2.1 search() & match()
    • 2.2 findall() & finditer()
    • 2.3 fullmatch() & split()
    • 2.4 正则表达式的转义
  • 3.正则表达式规则
    • 3.1 正则替换和编译
    • 3.2 正则表达式
      • 区间
      • 符号
      • 快捷标识
      • ^ $
      • 正则重复
      • 贪婪模式和非贪婪模式
      • 正则分组
      • 分组向后引用
      • 捕获分组和非捕获分组
      • 命名分组
      • 正则标记
      • 零宽断言
      • 内联标记

1.正则表达式的特点和优势 1.1 独立性
正则表达式运行的引擎是独立的,在几乎所有语言中都存在有正则表达式模块,正则表达式语法在各种语言上都是一样的,但是在实现方式上不尽相同。
1.2 优势
1.2.1 过滤查找
1.2.2 验证输入是否合法
2.正则搜索方法 2.1 search() & match()
2.1.1 search() 和 match() 查找
	# 差异:
	re.search()依据正则表达式进行匹配
	re.match()只从字符串的开头匹配
	# 相同点:
	两者只会输出匹配找到的第一个符合要求的子字符串的match对象
	查找到结果返回match对象,没有则返回None
	# 实例
	import re  # 导入re模块
	ret1 = re.search(r"sanle", "hello sanle")  # 使用re.search()方法查找
	print(ret1)  # 返回一个match对象 或者 None  结果:
	print(ret1.group())  # 通过match对象的group属性,访问其内容 结果:sanle
	
	ret2 = re.match(r"hello", "hello sanle")  # 使用re.search()方法查找
	print(ret2)  # 返回一个match对象 或者 None  结果:None
	
	# result.start() result.end() 下标左闭右开区间 即[m,n)
	print(ret2.start())  # 输出匹配字符串的开始下标
	print(ret2.end())  # 输出匹配字符串的结束下标
	print(ret2.group())  # 输出匹配到的字符串
	
	# 结果:0 5 hello 即0->h ... 5->空格 hello为匹配到的字符串

2.2 findall() & finditer()
2.2.1 findall()和finditer()
	# 规则:
	# 相同点:
	findall 或 finditer 匹配所有符合要求的字符串
	# 不同点:
	findall找到所有匹配内容,放到一个列表里返回
	finditer找到所有内容,返回一个迭代器,惰性求值
	
	finditer 遍历后得到的每个内容都是一个match对象,需要调用group来得到里面的具体的匹配字符串
	findall 直接返回匹配的字符串列表
	# Pattern.findall(string[,pos][,endpos]) 查询所有匹配,结果受到分组影响
	# 如果没有分组,则返回与整个模式匹配的字符串列表。
	# 如果恰好有一个组,请返回匹配该组的字符串列表。
	# 如果存在多个组,则返回与组匹配的字符串的元组列表。
	# 非捕获组不会影响结果的形式。使用了分组之后,findall不会输出分组以外的内容。

	# 实例
	import re
	ret = re.findall("s.{6}","hello snale snachaung nihao world ssssssss")
	print(ret)  # findall 返回匹配字符串组成的列表
	
	# 结果:
	# ['snale s', 'sssssss']
	
	result = re.findall("s.{6}","hello snale snachaung nihao world ssssssss")
	for i in result:
	    print(i)  # findall 返回列表 遍历元素
	
	# 结果:
	# sanle s
	# sssssss
	
	
	ret = re.finditer("s.{6}","hello snale snachaung nihao world ssssssss") # 返回一个迭代器
	print(ret)  # finditer 返回iterator,即迭代器
	for i in ret:
	    print(i)  # 从迭代器中得到了match对象 需要调用其group来遍历其匹配字符串内容
	    print(i.group())  # 从match对象中得到匹配的字符串
	
	# 结果:
	# 
	# 
	# sanle s
	# 
	# sssssss

	print(re.findall('[a-zA-Z]d{2,}','a1bc22342459f9849'))  # ['c22342459', 'f9849']
	print(re.findall('[a-zA-Z](d{2,})','a1bc22342459f9849'))  # ['22342459', '9849']
	# 使用分组功能,又要输出全部内容,那么就在整体外面再加一个括号
	print(re.findall('([a-zA-Z](d{2,}))','a1bc22342459f9849'))  # [('c22342459', '22342459'), ('f9849', '9849')]


2.3 fullmatch() & split()
	# fullmatch(string[,pos[,endpos]]) 全部匹配
	import re
	print(re.search("张三","法外狂徒张三,来长沙了"))  # 整个字符串进行匹配 
	
	print(re.match("张三","法外狂徒张三,来长沙了"))  # 只匹配字符串开始 None
	print(re.search("^张三","法外狂徒张三,来长沙了"))  # 只匹配字符串开始 None
	print(re.match("张三","法外狂徒张三,来长沙了"[4:]))  # 
	
	print(re.fullmatch("张三","法外狂徒张三,来长沙了"))  # 匹配字符串开始和结束位置 None
	print(re.search("^张三$","法外狂徒张三,来长沙了"))  # 匹配字符串开始和结束位置 None
	
	print(re.fullmatch("张三","法外狂徒张三,来长沙了"[4:6]))  # 
	
	# split(string,maxsplit=0) 根据匹配分割 受到分组的影响
	print(re.split('[+-*/]','9+7-8*6/5'))  # 结果:['9', '7', '8', '6', '5']
	
	# 捕获分组 将匹配到的所有信息都匹配出来
	print(re.split('([+-*/])','9+7-8*6/5'))  # 结果:['9', '+', '7', '-', '8', '*', '6', '/', '5']
	
	# maxsplit=0 指定分割的次数 默认是0不受限制
	print(re.split('(?:[+-*/])','9+7-8*6/5',maxsplit=2))  # ['9', '7', '8*6/5']
	print(re.split('([+-*/])','9+7-8*6/5',maxsplit=2))  # ['9', '+', '7', '-', '8*6/5']
2.4 正则表达式的转义
2.4.1 python中正则表达式转义工作流程
	python正则表达式转义两次,分别是python自己转义一次和正则自己转义一次如:\t -->tab-->tab
	即 python自己转义\为  t为tab键,之后交给正则来再一次转义即tab转义为tab 自动忽略单个的
	
	正则表达式前+r表示抑制第一次的python转义,使python
	直接将正则表达式传递给正则去转义,即只进行正则的转义,减少失误
	
	r'tdv' -不转义字符,保持原始字符串 等价于 '\tdv' 即表示以raw string格式进行定义,可以防止字符串规避反斜杠的转义 直接将正则表达式传递给正则去转义
	f'gajeo{name}' -定义格式字符串
	b'12' -字符串bytes类型,以便服务器或浏览器识别bytes数据类型;
	
	print(u'中国')
	print(u'china')
	-字符串前面加u表示以Unicode格式进行编码,往往用来解决中文乱码问题,一般英文字符串基本都可以正常解析,而中文字符串必须表明用什么编码,否则就会乱码。
	# 实例
	import re
	result = re.search("snachaung \ttongle", "hello world,snachaung ttongle")
	print(result)
	
	# 结果: 
	
	result = re.search(r"snachaung \ttongle", "hello world,snachaung ttongle")
	print(result)

	# 结果:None
	
	# 分析:前者没有+r即正则表达式进行了两次转义,先是\t->t,然后是t->tab;后者是只经历 \t->tab 然后丢弃单个的
3.正则表达式规则 3.1 正则替换和编译
3.1.1 正则替换
	# 格式:
	re.sub("匹配原则","替换内容",string)
	匹配的所有元素都替换
	# 实例
	import re
	str1 = "hello ,i'm learning python python"
	print(re.sub("p.{2}","xixi",str1))
	# hello ,i'm learning xixihon xixihon
3.1.2 正则编译
	import re
	msg = "hello my name is Jack Cali"
	msg2 = "hello my name is Rose"
	# 直接查找
	result = re.findall("iss(.*)$", msg)
	result2 = re.findall("iss(.*)$", msg2)
	print(result, result2)
	
	# 先编译再查找
	reg = re.compile("iss(.*)$")
	print(reg.findall(msg))
	print(reg.findall(msg2))

	# 区别
	pass
3.2 正则表达式 区间
3.2.1 区间
	# 区间: [] 根据ascii码确定区间范围 --要求ascii码小的在前,ascii码大的在后面如:[a-z]a->97,z->122
	# 可以[A-z] A->65 z->122
	# [] 区间表示 任选括号里一个字符进行匹配
	# 实例
	import re
	ret = re.findall("[12pP]x", "2px 1xx Python pxoo")  # 匹配中括号内任意一个字符开头,且以x结尾的两个长度的字符串
	print(ret)
	ret = re.findall("[0-9]", "124354raskgreg-grme23")  # 匹配数字0-9任意字符
	print(ret)
	ret = re.findall("[A-Z]", "124354raskgreg-grme23")  # 匹配大写字母A-Z
	print(ret)
	ret = re.findall("[a-z]", "124354raskgreg-grme23")  # 匹配小写字母a-z
	print(ret)
	ret = re.findall("[A-Za-z0-9]", "124354raskgreg-grme23")  # 匹配大小写字母和数字0-9
	print(ret)
	ret = re.findall("[a-z0-9A-Z-]", "124354raskgreg-grme23")  # 匹配大小写字母和数字0-9及-
	print(ret)
3.2.2 区间取反
	ret = re.findall(r"[^A-z][0-9]","few2345rg43h6n5jdth")  # 匹配不以A-z开头且匹配第二位是0-9数字的字符串
	print(ret)
符号
3.2.3 匹配或
	import re
	msg = "四是四,十是十 十四是十四 四十是四十"
	ret = re.search(r"四|十", msg)
	print(ret.group())
	ret2 = re.findall(r"四|十", msg)
	print(ret2)
3.2.4 .占位符 
	# 表除(n以外)的任意字符
	import re
	ret = re.findall("p.thon","pXthon python p-thon pthon pnthon p thon")
	print(ret)
3.2.5 ^ $
	import re
	ret = re.findall(r"^python","python1 is python")
	print(ret)
	
	ret = re.findall(r"python$","python1 is python")
	print(ret)
	
	ret = re.findall(r"^python$","python1 is python")
	print(ret)
3.2.6 正则重复
	# 通配符: * ? +
	# ? 匹配前一项0次或1次
	# + 匹配前一项1次以上 1-n次
	# * 匹配前一项任意次 0-n次
	# {n,m} 匹配前一项n-m次 {n,} {,m} {n}
	# 实例
	import re
	ret = re.findall('py?', "pythonppyy")
	print(ret)  # 结果:['py', 'p', 'py']
	
	ret = re.findall('py+', "pythonppyy")
	print(ret)  # 结果:['py', 'pyy']
	
	ret = re.findall('py*', "pythonppyy")
	print(ret)  # 结果:['py', 'p', 'pyy']
	
	ret = re.findall('py{1,3}', "pythonppyy")
	print(ret)  # 结果:['py', 'pyy']
	
	ret = re.findall('py{1,}', "pythonppyyyy")  # 匹配前一项1次到多次
	print(ret)  # 结果:['py', 'pyyyy']
	
	ret = re.findall('py+', "pythonppyyyy")  # 匹配前一项1次到多次
	print(ret)  # 结果:['py', 'pyyyy']
	
	ret = re.findall('py{,3}', "pythonppyyyy")  # 匹配前一项3次以下
	print(ret)  # 结果:['py', 'p', 'pyyy']
	
	ret = re.findall('py{3}', "pythonppyyyy")  # 匹配前一项3次
	print(ret)  # 结果:['pyyy']
快捷标识
3.2.7 快捷标识
	A 匹配字符串开始
	b 匹配词边界
	B 匹配非词边界
	w 匹配单词字符 a A 123 中文
	W 匹配非单词字符
	d 匹配数字
	D 匹配非数字
	s 匹配空白
	S 匹配非空白
	# 实例
	# 匹配字符串的开始
	import re
	ret = re.findall(r"Ahello", "hello world hello")
	print(ret)
	
	# 词边界
	ret = re.findall(r"bwordB", "word123 word# abcword #word你好")
	print(ret)
	
	# 匹配单词字符
	ret1 = re.findall(r"wwordW", "word123 word# abcword #word你好")
	print(ret1)
	
	ret2 = re.findall(r"wwordW", "中国word*56w A1word# abcword #word你好")
	print(ret2)
	
	# 匹配数字和非数字
	ret = re.findall(r"dwordD", "word123 1word# abcword #word你好")
	print(ret)
	
	# 匹配空白和非空白
	ret = re.findall(r"swordS", "word123 word# abcword #word你好")
	print(ret)
^ $
	import re
	ret = re.findall(r"^python","python1 is python")  # 匹配字符串以python开头的python字符串
	print(ret)  # 结果:['python']
	
	ret = re.findall(r"python$","python1 is python")  # 匹配字符串以python结尾的python字符串
	print(ret)  # 结果:['python']
	
	ret = re.findall(r"^python$","python1 is python")  # 匹配以python字符串开头和结尾的python字符串
	print(ret)  # 结果:[]
正则重复
	# 通配符: * ? +
	# ? 匹配前一项0次或1次
	# + 匹配前一项1次以上 1-n次
	# * 匹配前一项任意次 0-n次
	# {n,m} 匹配前一项n-m次 {n,} {,m} {n}
	import re
	ret = re.findall('py?', "pythonppyy")
	print(ret)  # 结果:['py', 'p', 'py']
	
	ret = re.findall('py+', "pythonppyy")
	print(ret)  # 结果:['py', 'pyy']
	
	ret = re.findall('py*', "pythonppyy")
	print(ret)  # 结果:['py', 'p', 'pyy']
	
	ret = re.findall('py{1,3}', "pythonppyy")
	print(ret)  # 结果:['py', 'pyy']
	
	ret = re.findall('py{1,}', "pythonppyyyy")  # 匹配前一项1次到多次
	print(ret)  # 结果:['py', 'pyyyy']
	
	ret = re.findall('py+', "pythonppyyyy")  # 匹配前一项1次到多次
	print(ret)  # 结果:['py', 'pyyyy']
	
	ret = re.findall('py{,3}', "pythonppyyyy")  # 匹配前一项3次以下
	print(ret)  # 结果:['py', 'p', 'pyyy']
	
	ret = re.findall('py{3}', "pythonppyyyy")  # 匹配前一项3次
	print(ret)  # 结果:['pyyy']
贪婪模式和非贪婪模式
	# 贪婪模式 尽可能地匹配长的字符串
	# 非贪婪模式 从左至右依次匹配 匹配到就结束本字段匹配 然后进行后面的字符串匹配 (+? *? {2,4}?)
	
	# 默认为贪婪模式
	import re
	ret = re.findall("py*","pythonpyyyyy")
	print(ret)  # 结果:['py', 'pyyyyy']
	
	# 非贪婪模式
	import re
	msg = "cats and dogs,cats1 and dogs1"
	print(re.findall(r"c.*?s",msg))  # 结果:['cats', 'cats']
	
	import re
	ret = re.findall("py*?","pythonpyyyyy")
	print(ret)  # 结果:['p', 'p']
正则分组
	# group 默认参数是0 表示输出整个匹配字符串
	#        参数 n (n>0)输出第几个组的匹配字符串
	msg = "tel:173-7572-2991"
	ret = re.search(r"(d{3})-(d{4})-(d{4})",msg)
	print(ret.group())  # 输出匹配到的字符串
	print(ret.group(0))  # 输出匹配到的字符串
	print(ret.group(1))  # 输出匹配到的第一组的子字符串
	print(ret.group(2))  # 输出匹配到的第二组的子字符串
	print(ret.group(3))  # 输出匹配到的第三组的子字符串
分组向后引用
	# 前面的匹配内容会保存在内存里面,后面匹配从内存里查找
	msg = "tel:173-7572-2991"
	msg = "tel:173-7572-173"
	ret = re.search(r"(d{3})-(d{4})-1", msg) # 1表示匹配第一组子字符串
	print(ret.group())  # 只有match对象才有group属性  AttributeError: 'NoneType' object has no attribute 'group'
	# 结果:173-7572-173
捕获分组和非捕获分组
	# 捕获分组
	# 分组之后匹配到的数据会发放在内存里,并且给定一个从1开始的索引
	# 捕获分组是可以进行分组向后引用
	
	# 非捕获分组(?:正则表达式)
	# 只分组不捕获 匹配到的分组数据不放在内存里
	# 不能使用分组向后引用
	import re
	msg = "tel:173-7572-7572"
	ret = re.search(r'(?:d{3})-(d{4})-1', msg)
	print(ret.group(0))  # 打印匹配字符串 结果:173-7572-7572
	print(ret.group(1))  # 打印第一个捕获分组  结果:7572
	
	# 如果有捕获分组 findall只会匹配捕获分组里的内容
	import re
	msg = "tel:173-7572-7572"
	ret = re.findall(r'(?:d{3})-(d{4})-1', msg)
	print(ret)  #结果:['7572']
命名分组
	# 命名分组 (?P<名字>正则表达式)
	import re
	msg = "tel:173-7572-7572"
	ret = re.search(r'(?Pd{3})-(d{4})-2', msg)
	print(ret.group())
	print(ret.group("first"))
	print(ret.groupdict())
	
	# 结果:173-7572-7572
	173
	{'first': '173'}
正则标记
	# 正则标记 --改变正则表达式的默认匹配规则 如大小写是否敏感
	msg = """YOU JUMP, I GO
	you jump, i go"""
	# 对大小写不敏感的标记
	ret = re.findall(r"JUMP", msg, re.I)  # 忽略大小写
	print(ret) # 结果:['JUMP', 'jump']
	
	# 多行模式
	ret = re.findall(r"^YOU JUMP, I GO$", msg, re.I | re.M)  # 忽略大小写 且运用多行模式
	print(ret)  # 结果:['YOU JUMP, I GO', 'you jump, i go'] 
	
	# re.S 让.匹配任意字符 包括换行符
	ret = re.findall(r"^you.*go$", msg, re.I | re.S)  # 忽略大小写 且让.匹配任意字符包括换行符
	print(ret)  # 结果:['YOU JUMP, I GO nyou jump, i go']
零宽断言
	# 零宽断言
	# 不占用匹配宽度,只用来确定位置
	# 与驴不占用匹配宽度,只用来确定位置
	str1 = "红鲤鱼与绿鲤鱼与驴"
	print(re.findall(r".鲤鱼(?=与驴)", str1))  # 匹配后面有与驴的鲤鱼
	print(re.findall(r".鲤鱼(?!与驴)", str1))  # 匹配后面没有与驴的鲤鱼
	print(re.findall(r"(?<=红)鲤鱼.", str1))  # 匹配前面有红的鲤鱼
	print(re.findall(r"(? 
内联标记 
	# 修饰符         功能
	# (?imx)re   正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
	# (?imx:re)   在括号中使用i, m, 或 x 可选标志
	# 内联标记 只想在某个地方使用忽略 而不在其他地方忽略?可以使用内联标记
	# 内联标记实际就是匹配模式的部分范围生效
	# re.IGNORECASE 与 (?i:) 括号内忽略大小写
	# re.MULTILINE 与 (?m:) '^'和'$'的跨行限制开头结尾 括号内实现多行模式
	# re.DOTALL 与 (?s:) 让 '.'支持换行符的匹配。 括号内实现.代表所有字符包括换行/n
	# re.VERBOSE 与 (?x:) 支持注释 括号内实现注释
	# re.ASCII 与 (?a:) 让 w, W, b, B, d, D, s 和 S 只匹配ASCII 括号内只匹配ascii
	
	# (?i:正则表达式) 括号内大小写不敏感
	a = re.compile("(super) APP")
	x = a.search("SUPER APP")
	print(x)                #不能用super匹配SUPER
	
	a = re.compile("(?i:super) APP")  # 忽略大小写进行匹配
	x = a.search("SUPER APP")
	print(x)       #     #可以用super匹配SUPER 。
	
	
	# (?i)re
	import re
	ret = re.findall('(?i)^python$','PYTHON')  # 忽略大小写
	print(ret)  # 结果:['Python']
	ret = re.findall('(?i)^python$','Pythonnpython')
	print(ret)  # 结果:[]
	ret = re.findall('(?im)^python$','Pythonnpython')  #多行模式
	print(ret)  # 结果:['Python', 'python']
	
	# (?imx:re)
	import re
	msg = "Hello Python"
	ret = re.findall('(?i:hello) python',msg)
	print(ret)  # 结果:[]
	ret = re.findall('(?i:hello) Python',msg)
	print(ret)  # 结果:['Hello Python']
	
	# (?is:re) 大小写不敏感 且.代表左右的字符串包含换行n
	a = re.compile(r'(?i:天天.*up)')
	str_ = '天天UP天天nUP'
	x = re.match(a,str_)
	print(x)       #     #点号不能匹配换行符
	
	a = re.compile(r'(?is:天天.*up)')
	str_ = '天天UP天天nUP'
	x = re.match(a,str_)
	print(x)     #    #支持忽略大小写,并让点号匹配换行符
	
	# 排除标记方式
	
	# 比如flasg属性中 已经制定了忽略大小写 但是在某些地方一定会
	# 不能忽略大小写 那么就可以设置排除标记方式
	# 格式:(?-im:re) im为要忽略的属性 可以是其他任何存在的属性
	
	a = re.compile(r'(?-i:None).*empty',re.IGNORECASE)
	str_1 = 'none expressing EMPTY'
	str_2 = 'None expressing EMPTY'
	x = a.match(str_1)
	print(x)  # 结果:None 因为str_1中none大小写敏感 所以无匹配项
	
	y = a.match(str_2) # 分组内大小写敏感 分组外大小写不敏感
	print(y)  # 结果:
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/971698.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号