了解如何使用 Python 的内置 re 模块使用 match、search、finditer 和 sub 等函数来使用多种字符串匹配技术。
如何在Python中使用正则表达式?一个正则表达式是形成一个搜索模式字符的特殊序列,它可以被用来检查一个字符串包含指定的模式,也可以用于提取所有匹配模式等等。
正则表达式无处不在,从验证电子邮件地址、密码、日期格式到在搜索引擎中的使用,因此它是任何开发人员的必备技能,并且大多数编程语言都提供了正则表达式功能。
Python如何使用正则表达式?如果你熟悉 Linux,我想你已经看到了一些使用 sed 和 grep 命令的正则表达式,但在本教程中,我们将 在 Python 中重新模块。以下是我们将介绍的技术:
- 匹配字符串
- 搜索方法
- 查找多个匹配项
- 替换匹配
在本教程中,我们不会涵盖从头开始构建正则表达式的基础知识,相反,我们将更多地关注如何有效地在 Python 上使用正则表达式。
Python正则表达式用法示例:匹配字符串
有关如何使用re.match()
函数的演示,假设你要验证用户密码。例如,你要确保他们输入的密码长度至少为 8 个字符,并且至少包含一位数字。以下代码执行此操作:
import re # stands for regular expression
# a regular expression for validating a password
match_regex = r"^(?=.*[0-9]).{8,}$"
# a list of example passwords
passwords = ["pwd", "password", "password1"]
for pwd in passwords:
m = re.match(match_regex, pwd)
print(f"Password: {pwd}, validate password strength: {bool(m)}")
如何在Python中使用正则表达式?match_regex
是负责验证我们前面提到的密码标准的正则表达式:
^
: 开始字符。(?=.*[0-9])
:确保字符串至少有一个数字。.{8,}
:确保字符串至少有 8 个字符。$
: 结束字符。
然后我们使用一个密码列表来匹配,这是输出:
Password: pwd, validate password strength: False
Password: password, validate password strength: False
Password: password1, validate password strength: True
不出所料,前两次失败,最后一次成功。第一个密码 ( pwd
) 少于 8 个字符,第二个不包含数字,而第三个至少有 8 个字符并包含一个数字。
请注意,我们re.match()
使用内置方法包装了该bool()
方法以返回一个布尔值,指示字符串是否与模式匹配。
搜索方法
Python如何使用正则表达式?演示该re.search()
方法的一个很好的例子是在字符串中搜索特定模式。在本节中,我们将尝试从Windows 中的ipconfig命令输出的一部分中提取 IPv4 地址:
import re
# part of ipconfig output
example_text = """
Wireless LAN adapter Wi-Fi:
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::380e:9710:5172:caee%2
IPv4 Address. . . . . . . . . . . : 192.168.1.100
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.1.1
"""
# regex for IPv4 address
ip_address_regex = r"((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}"
# use re.search() method to get the match object
match = re.search(ip_address_regex, example_text)
print(match)
不要太担心ip_address_regex
表达式,它基本上验证一个 IPv4 地址(确保总数4中的每个数字不超过255)。
re.search()
在这种情况下,我们使用搜索有效的 IPv4 地址,这是输出:
<_sre.SRE_Match object; span=(281, 292), match='192.168.1.1'>
re.search()
返回一个匹配对象,该对象具有找到的字符串和实际字符串的开始和结束索引,在这种情况下,它'192.168.1.1'
作为匹配的字符串返回。你可以使用:
match.start()
获取找到的模式的第一个字符的索引。match.end()
获取找到的模式的最后一个字符的索引。match.span()
以元组 (start
,end
) 的形式获取开始和结束。match.group()
获取找到的实际字符串。
如你所见,它只返回第一个匹配项并忽略剩余的有效 IP 地址。在下一节中,我们将看到如何在一个字符串中提取多个匹配项。
Python正则表达式用法示例:查找多个匹配项
我们将使用相同命令 ( ipconfig )的输出,但这次我们将尝试使用正则表达式来匹配 MAC 地址:
import re
# fake ipconfig output
example_text = """
Ethernet adapter Ethernet:
Media State . . . . . . . . . . . : Media disconnected
Physical Address. . . . . . . . . : 88-90-E6-28-35-FA
Ethernet adapter Ethernet 2:
Physical Address. . . . . . . . . : 04-00-4C-4F-4F-60
Autoconfiguration IPv4 Address. . : 169.254.204.56(Preferred)
Wireless LAN adapter Local Area Connection* 2:
Media State . . . . . . . . . . . : Media disconnected
Physical Address. . . . . . . . . : B8-21-5E-D3-66-98
Wireless LAN adapter Wi-Fi:
Physical Address. . . . . . . . . : A0-00-79-AA-62-74
IPv4 Address. . . . . . . . . . . : 192.168.1.101(Preferred)
Default Gateway . . . . . . . . . : 192.168.1.1
"""
# regex for MAC address
mac_address_regex = r"([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})"
# iterate over matches and extract MAC addresses
extracted_mac_addresses = [ m.group(0) for m in re.finditer(mac_address_regex, example_text) ]
print(extracted_mac_addresses)
定义正则表达式后,我们使用re.finditer()
函数查找传递的字符串中所有出现的 MAC 地址。
由于finditer()
返回匹配对象的迭代器,我们使用列表推导来仅提取使用group(0)
(整个匹配项)找到的 MAC 地址。查看输出:
['88-90-E6-28-35-FA', '04-00-4C-4F-4F-60', 'B8-21-5E-D3-66-98', 'A0-00-79-AA-62-74']
太棒了,我们已经成功提取了该字符串中的所有 MAC 地址。在下一节中,我们将看到如何使用正则表达式替换字符串中出现的模式。
替换匹配
Python正则表达式用法示例:如果你有网络抓取经验,你可能会遇到使用CloudFlare 等服务从电子邮件收集工具隐藏电子邮件地址的网站。在本节中,我们将完全这样做,给定一个包含电子邮件地址的字符串,我们将用'[email protected]'
令牌替换每个地址:
import re
# a basic regular expression for email matching
email_regex = r"[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+"
# example text to test with
example_text = """
Subject: This is a text email!
From: John Doe <john@doe.com>
Some text here!
===============================
Subject: This is another email!
From: Abdou Rockikz <example@domain.com>
Some other text!
"""
# substitute any email found with [email protected]
print(re.sub(email_regex, "[email protected]", example_text))
Python如何使用正则表达式?我们使用了re.sub()
带 3 个参数的方法,第一个是正则表达式(模式),第二个是替换找到的所有模式,第三个是目标字符串,这里是输出:
Subject: This is a text email!
From: John Doe <[email protected]>
Some text here!
===============================
Subject: This is another email!
From: Abdou Rockikz <[email protected]>
Some other text!
太好了,正如我们预期的那样,该re.sub()
函数返回通过用指定的替换(第二个参数)替换 string 中模式最左边的非重叠出现而获得的字符串。
结论
如何在Python中使用正则表达式?现在你已经掌握了在 Python 中使用正则表达式的技能,注意我们没有涵盖re模块提供的所有方法,还有其他方便的函数,比如split()
and fullmatch()
,所以我强烈建议你查看Python 的官方文档。