最新消息:欢迎光临 魔力 • Python!大家可以点开导航菜单中的【学习目录】,这个目录类似图书目录,更加方便学习!

Python3萌新入门笔记(42)

Python教程 小楼一夜听春语 3673浏览 0评论

这一篇教程是关于内置模块的最后一部分,更多的内置模块大家可以查询官方文档进行了解。

十三、re模块

在《Python3萌新入门笔记(23)》中,我们接触过正则表达式的使用,并且使用了re模块中的match()函数和compile()函数。

示例代码:

import re

print(re.match(r'Python.', 'Python\n', re.DOTALL))  # 匹配结果为:<_sre.SRE_Match object; span=(0, 7), match='Python\n'>
print(re.match(r'Python.', 'Python\r'))  # 匹配结果为:<_sre.SRE_Match object; span=(0, 7), match='Python\r'>
print(re.match(r'Python.', 'Python!'))  # 匹配结果为:<_sre.SRE_Match object; span=(0, 7), match='Python!'>
print(re.match(r'Python.', 'Python\n'))  # 匹配结果为:None

pat=re.compile(r'^[A-Z][0-9a-z]{5,}') # 预编译表达式:由字母与数字组成,首位为大写字母,长度6位以上的字符串。
print(pat.match('Ab12345'))
print(pat.match('Ab123'))
print(pat.match('ab1234'))
print(pat.match('A@1234'))

除了上述两个函数,re模块中还有其它一些函数供我们调用(这里只标出主要参数)。

search(pattern, string):从字符串参数string中查找与正则表达式pattern相匹配的子字符串,如果查找到匹配的子字符串,返回match对象,否则,返回None。

通过search()函数获取的match对象,可以通过group()方法获取其中的子字符串。

示例代码:

result = re.search(r'小楼.{2}', '帅帅的小楼哥哥!迷人的小楼欧巴!')
print(result)  # 显示输出结果为:<_sre.SRE_Match object; span=(3, 8), match='小楼哥哥'>
print(result.group())  # 显示输出结果为:小楼哥哥

print(re.search('楼叔.+', '帅帅的小楼哥哥!迷人的小楼欧巴!'))  # 显示输出结果为:None

不过,search只能获取首个匹配的子字符串。

如果想获取到所有匹配的子字符串,我们可以使用findall()函数。

findall(pattern, string):从字符串参数string中查找所有与正则表达式pattern相匹配的子字符串,如果查找到匹配的子字符串,返回包含所有子字符串的列表,否则,返回空列表。

示例代码:

result = re.findall(r'小楼.{2}', '帅帅的小楼哥哥!迷人的小楼欧巴!')
print(result)  # 显示输出结果为:['小楼哥哥', '小楼欧巴']

print(re.findall(r'楼叔.+', '帅帅的小楼哥哥!迷人的小楼欧巴!'))  # 显示输出结果为:[]

findall()函数能够把所有匹配的子字符串全部保存到列表。

当匹配到的子字符串数量比较庞大,不想一次性得到所有匹配结果时,我们可以使用finditer()函数。

finditer(pattern, string):返回在字符串string中所有非重叠匹配所生成的match对象的迭代器。

示例代码:

result=re.finditer(r'小楼.{2}', '帅帅的小楼哥哥!迷人的小楼欧巴!')
for i in result:
    print(i.group())

除了查询功能,re模块还提供了split()函数,用于对字符串进行分割。

split(pattern, string, maxsplit=0):参数pattern用于匹配分隔符,根据匹配的分隔符对参数字符串string进行分割,返回分割后的子字符串列表。参数maxsplit为最大分割次数。如果没有匹配的分隔符,返回结果为包含参数字符串string的列表。

result=re.split(r'\.+', '小楼好帅...小楼好棒.小楼好厉害')
print(result)# 显示输出结果为:['小楼好帅', '小楼好棒', '小楼好厉害']
result=re.split(r'\.+', '小楼好帅...小楼好棒.小楼好厉害',1)
print(result)# 显示输出结果为:['小楼好帅', '小楼好棒..小楼好厉害']

print(re.split(r',+', '小楼好帅...小楼好棒..小楼好厉害'))  # 显示输出结果为:['小楼好帅...小楼好棒.小楼好厉害']

接下来,是fullmatch()函数。

fullmatch(pattern, string):如果整个字符串与正则表达式匹配,则返回相应的match对象。如果字符串与正则表达式不匹配,则返回None;注意这与零长度匹配不同。

print(re.fullmatch(r'小楼.+', '小楼帅哥'))  # 显示输出结果为:<_sre.SRE_Match object; span=(0, 6), match='小楼帅哥'>
print(re.fullmatch(r'小楼.{2}', '小楼帅哥'))  # 显示输出结果为:<_sre.SRE_Match object; span=(0, 6), match='小楼帅哥'>
print(re.fullmatch(r'小楼.{1}', '小楼帅哥'))  # 部分匹配,显示输出结果为:None

re模块中还有对match对象进行替换的函数sub()。

sub(pattern, repl, string, count=0):由参数repl取代字符串string中匹配的子字符串,并将整个字符串返回。如果找不到匹配的子字符串,返回没有改变的字符串string。参数repl可以是字符串,也可以是一个函数;如果是一个字符串,函数会处理字符串中的所有反斜杠。例如,“\n”转换为一个换行符,“\r”转换为回车符等等。如果不是有效的转义,则会被保留。反向引用,如“\1”,可以将匹配后的match对象中第1组字符串获取与repl组成新的字符串。

例如,有如下字符串:

names = r'李学庆,薛之谦,李茂,于波,李连杰,李光洁'

1、如果将所有3个字的李姓姓名中前两个姓名替换为“\”,示例代码如下:

print(re.sub(r'李.(?!,).', '\\\\', names, 2))  # 显示输出结果为:\,薛之谦,李茂,于波,\,李光洁

在上方代码中,大家注意以下几点:

  • “\\\\”最终显示为“\”,这是因为4条“\”会被Python解释器和正则表达式各转义一次。
  • 正则表达式中的“李.”和后方的“.”决定了匹配的长度为3位。
  • 正则表达式中的“(?!,).”为零宽度断言,表示从已匹配部分“李.”开始,向后方的第1个字符继续进行匹配验证,如果字符不是“,”,则通过“.”获取该字符,当前匹配成功完成;否则,获取到的子字符串不足3位,当前匹配失败。

2、如果将所有3个字的李姓姓名中前两个姓名的姓氏替换为“*”,示例代码如下:

print(re.sub(r'李(.)(?!,)(.)', r'*\1\2', names,2))  # 显示输出结果为:*学庆,薛之谦,李茂,于波,*连杰,李光洁

在上方代码中,当匹配成功时,两个“(.)”所获取的内容会存储到match对象的group中;这两组内容会被替换字符串中的“\1\2”获取到,形成反向引用。

3、获取所有2~3个字的李姓姓名,并加上“[]”。

print(re.sub(r'李.?(?!,).', lambda x: '[' + x.group() + ']', names))  
# 显示输出结果为:[李学庆],薛之谦,[李茂],于波,[李连杰],[李光洁]

在上方代码中,大家注意以下几点:

  • “李.?”和最后的“.”决定了匹配的长度为2~3位。
  • 正则表达式会先完成“李.?”的最大匹配(子字符串的前两位),然后,通过“(?!,)”对最后一位字符进行验证,如果不是“,”,通过“.”获取该字符,匹配为3位的姓名字符串;否则匹配为2位的姓名字符串。
  • lambda表达式会获取每一个匹配成功的match对象,通过group()方法获取到子字符串后,返回带有“[]”的字符串。

subn()函数与sub()函数用法一致,只不过返回的是包含新字符串和替换次数的元组。

示例代码:

print(re.subn(r'李.?(?!,).', lambda x: '[' + x.group() + ']', names)) 
# 显示输出结果为:('[李学庆],薛之谦,[李茂],于波,[李连杰],[李光洁]', 4)

 

如果你匹配的一个字符串,包含了一些可能被Python解释器解释为正则表达式运算符的字符,可以使用escape()函数进行全部转义。

escape(pattern):此函数能够将参数字符串pattern中,除了ASCII字符、数字和下划线“_”以外所有的字符进行转义,并返回新的字符串。

示例代码:

print(re.escape(r'C:\Users\Administrator\Desktop\date.dat'))  
# 显示输出结果为:C\:\\Users\\Administrator\\Desktop\\date\.dat

除了上述函数外,还有re.purge()函数,用于清空缓存中的正则表达式。

以上是关于re模块的相关函数,与这些函数一起使用的还包含了一些方法。例如,已经使用过的group()方法和groups()方法。

group([group1, …]):根据参数个数,返回结果为match对象中某一组的内容或多组内容的元组,参数group为0或者省略参数时,可获取被匹配的字符串,参数group大于0或为某一键值时,返回结果为对应的子字符串。

groups(default=None):返回结果为match对象中所有子字符串的元组,参数default可以指定某一组不存在时的默认值。

start([group]):返回结果为match对象中某一组子字符串在被匹配字符串中的起始位置。

end([group]):返回结果为match对象中某一组子字符串在被匹配字符串中终止位置的下一个位置。

span([group]):返回结果为match对象中某一组子字符串在被匹配字符串中起始位置与终止位置的下一个位置组成的元组。

groupdict(default=None):返回结果为match对象中所有子字符串与其键值的字典,参数default可以指定某一组不存在时的默认值。

示例代码:

path = r'C:\Users\Administrator\Desktop\\'  # 包含三级目录的路径
pat = re.compile(r'..\\(\w+)\\(\w+)\\(\w+)\\(\w+)?')  # 匹配三级或四级目录的表达式

result = pat.match(path)
print(result)  # 显示输出结果为:<_sre.SRE_Match object; span=(0, 31), match='C:\\Users\\Administrator\\Desktop\\'>
print(result.groups())  # 显示输出结果为:('Users', 'Administrator', 'Desktop', None)
print(result.groups(default='date'))  # 显示输出结果为:('Users', 'Administrator', 'Desktop', 'date')
print(result.group(0))  # 显示输出结果为:C:\Users\Administrator\Desktop\
print(result.group(1,2))  # 显示输出结果为:('Users', 'Administrator')
print(result.start(1))  # 显示输出结果为:3
print(result.end(1))  # 显示输出结果为:8
print(result.span(1))  # 显示输出结果为:(3,8)

dict_pat = re.compile(r'..\\(?P<一级目录>\w+)\\(?P<二级目录>\w+)\\(?P<三级目录>\w+)\\')  # 匹配三级目录并加入键值
result_dict = dict_pat.match(path)
print(result_dict.groupdict())  # 显示输出结果为:{'一级目录': 'Users', '二级目录': 'Administrator', '三级目录': 'Desktop'}
print(result_dict.group('一级目录'))  # 显示输出结果为:Users

在上方代码中,正则表达式中写入的“?P<…>”可以为获取的子字符串指定键值。

本节知识点:

re模块

本节英文单词与中文释义:

1、search:搜索

2、pattern:模式

3、find:发现

4、split:分割

5、full:完全

6、repl(replace):替换

7、sub:代替

8、subn(sub number):代替 次数

9、escape:规避

10、purge:清除

11、span:跨度

转载请注明:魔力Python » Python3萌新入门笔记(42)

头像
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网站 (可选)