我正在阅读“用Python自动化无聊的东西”这本书,但是在CH7的项目中遇到了一行代码。我在这里无法理解作者的逻辑。
问题可以在最后找到。项目:电话号码和电子邮件地址提取器。 https://automatetheboringstuff.com/chapter7
项目大纲是:
您的手机和电子邮件地址提取器需要执行以下操作:
- 从剪贴板中取出文字。
- 查找文本中的所有电话号码和电子邮件地址。
- 将它们放到剪贴板上。
以下是代码:
import re, pyperclip
#extracts phone number
phoneRegex = re.compile(r'''(
(\d{3}|\(\d{3}\))? # area code -> either 561 or (561)
(\s|-|\.)? # separator (if there is)
(\d{3}) # first 3 digits
(\s|-|\.) # separator
(\d{4}) # last 4 digits
(\s*(ext|x|ext.)\s*(\d{2,5}))? # extension
)''', re.VERBOSE)
#extracts email
emailRegex= re.compile(r'''(
[a-zA-Z0-9._%+-]+ # username
@ # @symbol
[a-zA-Z0-0._%+-]+ # domain name
(\.[a-zA-Z]{2,4}) # dot something
)''',re.VERBOSE)
# find matches in clipboard text.
text = str(pyperclip.paste()) #paste all string in to 'text' string
matches = []
for groups in phoneRegex.findall(text):
phoneNum= '-'.join([groups[1],groups[3],groups[5]]) #group 1- > area code, group 2-> separation, group 3 -> 699 etc
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. (our new string)
if len(matches) > 0:
pyperclip.copy('\n'.join(matches))
print('Copied to clipboard:')
print('\n'.join(matches))
else:
print('No phone numbers of email addresses found.')
我被困在这个部分:
for groups in phoneRegex.findall(text):
phoneNum= '-'.join([groups[1],groups[3],groups[5]]) #area code, first 3 digits, last 4 digits of phone number
if groups[8] != ' ':
phoneNum += ' x' + groups[8]
matches.append(phoneNum)
作者解释说这些是区号,前3位数字,以及从电话号码中提取的最后4位数字:
groups[1],groups[3],groups[5]
但这对我没有意义。请注意,这个for循环遍历每个元素,'groups'不是整个列表,它只是列表中的一个元素。因此,groups [1]将是第一个元素的第二个数字,而不是实际元素。
为了更好地说明我的问题,这是另一个例子:
num= re.compile(r'(\d+)')
for groups in num.findall('Extract all 23 numbers 444 from 2414 at, 1'):
print(groups)
输出:
23
444
2414
1
for groups in num.findall('Extract all 23 numbers 444 from 2414 at, 1'):
print(groups[0])
输出:
2
4
2
1
所以groups [0]不是元素,只是元素的一个数字 希望这是有道理的,因为我在理解他的推理方面遇到了很多麻烦。任何帮助将不胜感激。
更新:似乎group [0]是tupple的第一个元素
num= re.compile(r'(\d+)\D+(\d+)\D+(\d+)')
for groups in num.findall('Extract all 23 numbers 444 from 2414 at, 10,434,555'):
groups[0]
输出:
23
10
答案 0 :(得分:0)
findall()总是返回一个元组列表,你可以使用for循环逐个返回每个元组!
for groups in phoneRegex.findall(text):
phoneNum= '-'.join([groups[1],groups[3],groups[5]])
print(groups) #you can add one more line to check it out
结果是:
('800.420.7240', '800', '.', '420', '.', '7240', '', '', '') #one of the tuple in groups
每场比赛的第一组(组(0))将是整个正则表达式:
>>>phoneNumRegex = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)')
>>>mo = phoneNumRegex.search('My number is 415-555-4242.')
>>>mo.group(0)
'415-555-4242'