无法理解findall()和分组(Python)

时间:2016-10-03 04:48:29

标签: python for-loop findall

我正在阅读“用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

1 个答案:

答案 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'