python - 无法理解为什么加入 re.findall 的索引从 1 而不是 0 开始
问题描述
《用python自动化无聊的东西》一书中的代码
#! python3
# phoneAndEmail.py - Finds phone numbers and email addresses on the clipboard.
import pyperclip, re
phoneRegex = re.compile(r'''(
(\d{3}|\(\d{3}\))? # area code
(\s|-|\.)? # separator
(\d{3}) # first 3 digits
(\s|-|\.) # separator
(\d{4}) # last 4 digits
(\s*(ext|x|ext.)\s*(\d{2,5}))? # extension
)''', re.VERBOSE)
# Create email regex.
emailRegex = re.compile(r'''(
[a-zA-Z0-9._%+-]+ # username
@ # @ symbol
[a-zA-Z0-9.-]+ # domain name
(\.[a-zA-Z]{2,4}) # dot-something
)''', re.VERBOSE)
# Find matches in clipboard text.
text = str(pyperclip.paste())
matches = []
for groups in phoneRegex.findall(text):
phoneNum = '-'.join([groups[1], groups[3], groups[5]])
if groups[8] != '':
phoneNum += ' x' + groups[8]
matches.append(phoneNum)
for groups in emailRegex.findall(text):
matches.append(groups[0])
# Copy results to the clipboard.
if len(matches) > 0:
pyperclip.copy('\n'.join(matches))
print('Copied to clipboard:')
print('\n'.join(matches))
else:
print('No phone numbers or email addresses found.')
它会删除剪贴板中的电子邮件和电话号码。我的问题是线条
for groups in phoneRegex.findall(text):
phoneNum = '-'.join([groups[1], groups[3], groups[5]])
如果我理解正确,findall 方法会返回一个元组列表,其中每个元组都有每组正则表达式,例如
[(area code, separator, first 3 digits, separator, last 4 digits, extension), (area code, separator, first 3 digits, separator, last 4 digits, extension)]
但是由于列表和元组以索引 0 开头,并且我想加入每个元组项目的第一个、第三个和第五个项目,为什么不是那行
for groups in phoneRegex.findall(text):
phoneNum = '-'.join([groups[0], groups[2], groups[4]])
解决方案
在python(老实说,以及大多数其他正则表达式引擎)中,re
match
对象在成功匹配后总是至少有一个组。其中第一个(第 0 个索引)始终是完全匹配。
为了说明我所说的“完全匹配”是什么意思。这是这个简单的正则表达式 - r'hello\s+world'
。这将匹配字符串,例如hello world
andhello world
和 even foo hello world bar
。查看演示
现在该演示将有 3 个匹配项,在所有这些匹配项中,您会注意到右侧显示“完全匹配”并列出了匹配项,第一个字符串是hello world
,第二个是hello world
,第三个是hello world
那是完整的比赛。这只是完整的正则表达式匹配,没有任何捕获。
现在这是另一个匹配并捕获-的正则表达式r'hello\s+(world)'
。检查这个演示。
现在请注意,每场比赛有 2 个字段,一个是full match,与上次相同,另一个是Group 1。这是我们捕获的组 - world
。
总之,成功匹配后,完整匹配始终位于第 0 个索引处,然后是捕获的组。
阅读文档以获取更多信息。
推荐阅读
- pyspark - 如何将 Spark 数据帧(在 DataBricks 中)写入 Blob 存储(在 Azure 中)?
- twig - 使用 Twig 声明模板并在父模板的块之间传递附加内容
- c++ - Visual Studio C++ 中的错误代码 = 0x80070002
- elasticsearch - 弹性搜索是否使用以前的搜索频率?
- javascript - 使用 react-leaflet 渲染 TopoJSON
- ios - AppStore对应用多个版本号的审核
- java - 带有 limit(1) 的 Stream 评估流的每个元素
- elasticsearch - 如何存储有关用户已阅读哪些通知的信息?
- css - Gmail HTML 电子邮件覆盖的背景颜色
- r - 通过 XGBoost 交叉验证优化期间失败