Python中的正则表达式是一种强大的工具,用于在文本中搜索、匹配和处理特定模式的字符串。它们通过定义一种模式,使得可以轻松地搜索、替换、提取和验证文本数据,在Python中的正则表达式由re模块提供支持的。
正则表达式通常用于以下任务:
1.搜索与模式匹配的文本:你可以使用正则表达式来查找文本中是否包含特定模式的字符串,例如查找所有电子邮件地址或电话号码。
2.替换文本:正则表达式可以用于替换文本中的特定模式。例如,你可以将所有匹配的单词替换为另一个单词。
3.提取信息:你可以使用正则表达式从文本中提取特定模式的信息。例如,从文本中提取所有日期或数字。
4.验证输入:正则表达式可以用于验证输入是否符合特定的模式。例如,验证用户输入的电子邮件地址是否具有正确的格式。
1.匹配字符串
Python 中的re
模块是一个用于字符串中正则表达式操作的标准库,以下代码演示了如何使用 re.match()
函数来查找字符串中与给定模式匹配的部分。
代码示例:
# match()函数的使用
# \w匹配字母数字及下划线
# \s匹配任意空白字符,等价于 [\t\n\r\f].
# \d匹配任意数字,等价于 [0-9]
# [...]用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'
# [^...]不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
# ^匹配字符串的开头
# {n}精确匹配n个前面表达式。
import re
content='Hello 123 4567 World_This is a Regex Demo'
print(len(content)) # 41
# 使用re.compile()函数创建一个正则表达式模式对象pattern,模式是 r'^Hello\s\d\d\d\s\d{4}\s\w{10}'。该模式用来匹配以"Hello"开头,后面跟着一个空白字符,然后是三个数字,再一个空白字符,接着是四个数字,再是一个空白字符,最后是十个字母数字或下划线的字符串
pattern=re.compile(r'^Hello\s\d\d\d\s\d{4}\s\w{10}')
# 调用re.match(pattern, content)对content进行匹配,返回结果保存在result中
result=re.match(pattern,content)
print(result) # 打印匹配结果,结果是一个匹配对象
print(result.group()) # 打印匹配对象中与模式匹配的字符串
print(result.span()) # 打印匹配的位置,即匹配的字符串在原始字符串中的起始位置和结束位置
运行结果:
2.正则表达式匹配目标
#匹配目标
#group()会输出完整的匹配结果,而group(1)会输出第一个被()包围的匹配结果
import re
content='Hello 1234567 World_This is a Regex Demo' # 被匹配的文本字符串
pattern=re.compile(r'^Hello\s(\d{7})\s(\w{5})') # 编译后的正则表达式对象,其含义是:
# ^Hello:匹配以 "Hello" 开头的字符串
# \s:匹配一个空白字符(例如空格)
# (\d{7}):匹配七位数字,并将这七位数字作为一个分组。
# \s:再次匹配一个空白字符
# (\w{5}):匹配五个字母数字或下划线字符,并将这五个字符作为一个分组
result = re.match(pattern,content) # 执行匹配
print(result)
print(result.group())
print(result.group(1))
print(result.group(2))
print(result.span())
运行结果:
3.正则表达式中的贪婪匹配与非贪婪匹配
在正则表达式中,贪婪匹配和非贪婪匹配是两种常见的匹配策略,它们决定了正则表达式如何从字符串中匹配字符。**贪婪匹配(Greedy matching)**是正则表达式的默认行为。在贪婪匹配模式下,正则表达式会尽可能多地匹配字符,直到无法继续匹配为止。即使这种匹配超过了必要的最小匹配,它也会继续尝试匹配更多的字符。非贪婪匹配(Non-greedy matching),又称最小匹配或懒惰匹配,是通过在量词(如*
, +
, ?
, {n,}
)后面加上一个?
来启用的。在非贪婪模式下,正则表达式会尽可能少地匹配字符。
1.贪婪匹配
代码示例:
#贪婪匹配与非贪婪匹配
# 01贪婪匹配
import re
content='Hello 1234567 World_This is a Regex Demo'
# 编译一个正则表达式模式pattern,模式是 r'^He.*(\d+).*Demo$'
# ^He:表示字符串以 "He" 开头。
# .*:表示匹配任意个(包括0个)任意字符,. 表示任意字符,* 表示任意次数,这是一个贪婪模式,会尽可能多地匹配字符
# (\d+):括号表示一个分组,\d+ 表示匹配一个或多个数字。由于前面的 .* 是贪婪的,所以这个表达式会尽可能少地匹配数字,只要能满足整个表达式的匹配
# .*Demo$:再次使用 .* 进行贪婪匹配,Demo$ 表示字符串以 "Demo" 结尾
pattern=re.compile(r'^He.*(\d+).*Demo$')
result=re.match(pattern,content)
print(result) # 查看匹配结果,若匹配成功,则result是一个匹配对象;若失败,则为 None
print(result.group()) # 获取整个匹配的字符串,应输出'Hello 1234567 World_This is a Regex Demo'
print(result.group(1)) # 获取第一个分组的内容,即 \d+ 匹配的部分。因为 .* 的贪婪性,它尽可能地匹配了除最后一个数字以外的所有内容,所以group(1)应该只包含 '7'
运行结果:
2.非贪婪匹配
代码示例:
#02 非贪婪匹配
import re
content='Hello 1234567 World_This is a Regex Demo'
# He:匹配文本中的"Hello"的开头的"He"
# .*?:这是一个非贪婪的匹配,匹配尽可能少的任意字符直到遇到下一个符合模式的字符。因为它后面跟着\d+,所以它会停在数字开始的地方
# (\d+):这是一个捕获组,用于匹配一个或多个数字(\d+),并将这些数字作为一个分组保存,以便后面可以单独访问。
# .*:匹配从数字之后到字符串末尾前的任意字符
# Demo$:匹配字符串末尾的"Demo",$表示字符串的结束。
pattern=re.compile(r'He.*?(\d+).*Demo$')
result=re.match(pattern,content)
print(result)
print(result.group())
print(result.group(1)) # group(1)返回第一个捕获组的内容,在这个例子中,是字符串中的第一串数字1234567。
运行结果:
3.注意
需要注意的是,如果匹配的结果在字符串结尾,.*?就有可能匹配不到任何内容,因为它会匹配尽可能少的字符,例如:
import re
content='https://www.baidu.com/search/error.html'
result1=re.match(r'^https.*search/(.*)',content) # 贪婪匹配模式
result2=re.match(r'https.*search/(.*?)',content) # 非贪婪匹配模式
print("result1: ", result1.group(1))
print("result2: ",result2.group(1))
运行结果:
4.正则表达式中的修饰符
正则表达式可以包含一些可选标志修饰符来控制匹配的模式,而修饰符被指定为一个可选的标志。以下代码演示了如何使用正则表达式的修饰符来控制匹配的模式,特别是re.S
修饰符的用法。
#修饰符
import re
content = '''Hello 1234567 World_This
is a Regex Demo'''
# r'^He.*?(\d+).*?Demo$':这是正则表达式模式:
# ^He:^表示匹配必须从字符串的开始处开始,He则匹配字符串开始的"Hello"中的"He"
# .*?:非贪婪模式匹配任意字符,尽可能少的匹配直到下一个符合条件的字符
# (\d+):捕获组,匹配一个或多个数字
# .*?:再次使用非贪婪模式匹配任意字符,直到遇到最后的"Demo"
# Demo$:匹配字符串的末尾,必须以"Demo"结束
# re.S(或re.DOTALL):这个修饰符使.特殊字符能够匹配任何字符,包括换行符(默认情况下,.不匹配换行符)
pattern=re.compile(r'^He.*?(\d+).*?Demo$',re.S)
result=re.match(pattern,content)
print(result.group(1)) # 打印第一个捕获组的内容,即字符串中的数字1234567
# 由于使用了re.S修饰符,正则表达式可以跨越多行来找到匹配项。如果没有这个修饰符,.字符就不能匹配换行符,导致匹配失败。在这个例子中,使用re.S允许.*?匹配包括换行符在内的任意字符,从而正确地匹配并捕获所需的数字
运行结果:
5.转义匹配
使用Python的正则表达式库来匹配具有特殊字符的字符串。
代码示例:
# 转义匹配
import re
content='(百度)www.baidu.com'
# \(百度\):因为圆括号()在正则表达式中是特殊字符(用于定义捕获组),所以需要使用反斜杠\进行转义,使其表示字面意义上的括号
# www\.baidu\.com:同样的,点.也是一个特殊字符,它通常用来匹配除换行符之外的任何单个字符。在这里,我们需要匹配字面上的点,因此使用\.进行转义
pattern=re.compile(r'\(百度\)www\.baidu\.com')
result=re.match(pattern,content)
print(result.group())
运行结果:
6 search()方法匹配字符串
# search()
import re
content = 'Extra stings Hello 1234567 World_This is a Regex Demo Extra stings'
pattern=re.compile('He.*?(\d+).*Demo')
# 使用search方法在content字符串中搜索第一个符合pattern定义的模式的匹配。不同于match方法,search不要求模式从字符串的开头开始匹配,它会在整个字符串中搜索匹配
result=re.search(pattern,content)
print(result.group())
print(result.group(1))
运行结果:
7.使用正则表达式根据要求匹配歌手和歌曲
import re
# html这个字符串包含了HTML代码片段,其中包括了一个包含音乐列表的 <div> 元素
html = '''<div id="songs-list">
<h2 class="title">经典老歌</h2>
<p class="introduction">
经典老歌列表
</p>
<ul id="list" class="list-group">
<li data-view="2">一路上有你</li>
<li data-view="7">
<a href="/2.mp3" singer="任贤齐">沧海一声笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齐秦">往事随风</a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
<li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
<li data-view="5">
<a href="/6.mp3" singer="邓丽君"><i class="fa fa-user"></i>但愿人长久</a>
</li>
</ul>
</div>'''
# 正则表达式模式:
# <li.*? 匹配一个 <li> 标签及其可能的其他属性。
# active 匹配 class 属性中包含了 active 字符串的 <li> 元素。
# singer="(.*?)" 匹配 singer 属性值中的歌手名字。
# >(.*?)</a> 匹配了 <a> 标签中的文本内容,也就是歌曲名字。
# html 是待匹配的字符串。
# re.S 是一个标志,指定了在匹配中应该将换行符也视为普通字符。
result=re.search('<li.*?active.*?singer="(.*?)">(.*?)</a>',html,re.S)
if result:
print(result.group(1), result.group(2))
运行结果:
8.正则表达式中的sub()方法
使用Python中re
模块的 sub()
方法,用于替换字符串中与指定正则表达式模式匹配的部分。
代码示例:
#sub()方法
import re
content = '54aK54yr5oiR54ix5L2g'
# 这行代码使用了re模块的sub()方法来替换字符串content中匹配正则表达式模式\d+的部分为空字符串
# \d+ 是一个正则表达式模式,匹配一个或多个数字字符。
# ''是要替换匹配部分的内容,这里是空字符串,表示删除匹配到的数字
# content是待处理的字符串。
result=re.sub('\d+','',content)
print(result)
运行结果:
9.正则表达式处理日志内容
# 定义一个字符串变量log,其中包含一个日志条目,记录了日期、时间、日志级别和消息内容
log='2017-06-06 15:06:16,148 - root - DEBUG - logger debug message'
print(log.split('-')) # '-'是指定的分隔符,split()方法将根据这个分隔符来拆分字符串。将日志条目中的每个部分分隔开,并以列表的形式打印出来。
运行结果:
10.正则表达式中的findall()函数
# findall() 函数,用于在给定的字符串中查找所有与指定正则表达式模式匹配的部分。
import re
# 这行代码定义了一个字符串content,其中包含了一个HTML锚点链接。HTML锚点链接是一种在网页中创建超链接的方式,它允许用户点击链接跳转到同一页面的不同位置。这些位置通常是页面上的特定部分,例如标题、段落或者其他元素。
content='<a href="http://www.baidu.com">baidu</a>'
# 使用 re.compile()函数创建一个正则表达式对象 pattern,该对象用于匹配HTML锚点链接的<a>标签
# <a href="(.*?)">(.*?)</a>是一个正则表达式模式,它匹配了一个<a>标签,其中包含了href属性和链接文本
# (.*?) 是非贪婪匹配,用于捕获 href 属性值和链接文本
pattern=re.compile('<a href="(.*?)">(.*?)</a>')
# findall()函数在给定的字符串content中查找所有与正则表达式模式匹配的部分,并返回一个包含所有匹配项的列表
result=re.findall(pattern,content)
print(result)
print(result[0]) # 打印出了结果列表中的第一个匹配项
print(result[0][0]) # 打印出了第一个匹配项中的第一个捕获组,即链接的href属性值。href属性是 HTML<a>元素中的一个属性,用于指定超链接的目标地址(Hypertext REFerence)
运行结果:
以上内容总结自网络,整理不易,如有帮助欢迎转发,我们下次再见!