首页 > 解决方案 > 关于元组,我有什么遗漏吗?

问题描述

我正在尝试从“用 Python 自动化无聊的东西”中学习 Python,但遇到了一个我不太清楚的程序。

phone_regex = 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)



matches = []
for groups in phone_regex.findall(text):
    print('here')
    phone_number = '-'.join([groups[1], groups[3], groups[5]])
    if groups[8] != '':
        phone_number += ' x' + groups[8]
        matches.append(phone_number)

这显然不是全部,但我不明白当正则表达式中只有 6 个组时,如何存在组 [8]。此外,虽然我知道第一组 group[0] 应该是第一个,但我真的不明白如何......它是否只是这样工作,当有一个包含多个元组的大元组时,大一个被索引时被认为是第一个?

这显然不是全部,但我不明白当正则表达式中只有 6 个组时,如何存在组 [8]。此外,虽然我知道第一组 group[0] 应该是第一个,但我真的不明白如何......它是否只是这样工作,当有一个包含多个元组的大元组时,大一个被索引时被认为是第一个?

另外,这里的 for 循环是如何工作的?他们在循环什么?我认为添加类似 groups=groups[0:] 之类的东西对于在这种情况下迭代实际上彼此不同是必要的......

提前致谢。

标签: pythonregex

解决方案


请注意,某些捕获组具有嵌入的捕获组,这些捕获组也被计算在内。

因此:

  • (\d{3}|\(\d{3}\))?- 是第 1 组。
  • \(\d{3}\)-不是嵌入组,因为两个括号都被引用并按字面意思对待。
  • 分隔符前 3 位,第二个分隔符后 4 位是第 2 组到第 5 组。
  • (\s*(ext|x|ext.)\s*(\d{2,5}))?- 是第 6 组(有 2 个嵌入组)。
  • (ext|x|ext.)- 是第 7 组。
  • (\d{2,5})- 是第 8 组。

要查看每个组捕获的内容,请运行:

text = '123-456-9876 ext 22, (123)-456-9876'
for groups in phone_regex.findall(text):
    print(f'Whole match: {groups[0]}')
    n = 1
    for grp in groups[1:]:
        print(f'{n}: {grp:5}', end=', ')
        n += 1
    print()

我得到的结果是:

Whole match: 123-456-9876 ext 22
1: 123  , 2: -    , 3: 456  , 4: -    , 5: 9876 , 6:  ext 22, 7: ext  , 8: 22   , 
Whole match: (123)-456-9876
1: (123), 2: -    , 3: 456  , 4: -    , 5: 9876 , 6:      , 7:      , 8:      , 

并在评论中回答你的问题:我认为你应该避免像groups = groups[1:]这样的结构。在语法上它是正确的,但是这样你会试图弄乱已找到的结果。您可以像上面的代码一样阅读 groups[1:],但不要尝试在 那里保存任何东西。


推荐阅读