ZetCode

Python Match.groupdict() 方法

最后修改于 2025 年 4 月 20 日

Match.groupdict 简介

Match.groupdict 方法是 Python re 模块的一部分。它返回一个字典,其中包含匹配项的所有命名子组。

此方法在正则表达式操作返回的匹配对象上可用。它仅适用于包含命名捕获组的模式。

字典键是组名,值是匹配的字符串。未匹配的命名组将其值返回为 None

基本语法

Match.groupdict 的语法很简单

match.groupdict(default=None)

可选的 default 参数指定未匹配组的值。如果未提供,则未匹配的组在字典中将为 None

基本命名组匹配

让我们从一个使用命名组和 groupdict 的简单示例开始。

basic_groupdict.py
#!/usr/bin/python

import re

text = "Date: 2023-12-25"
pattern = re.compile(r'Date: (?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})')

match = pattern.search(text)
if match:
    print(match.groupdict())

此示例演示了使用命名组提取日期组件。 groupdict 方法将它们作为字典返回。

pattern = re.compile(r'Date: (?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})')

这里我们使用 (?P<name>...) 语法为年、月和日定义命名组。每个组捕获一个特定的日期组件。

print(match.groupdict())

groupdict 调用返回一个字典,其中我们的命名组作为键,其匹配值作为值。输出将是 {'year': '2023', 'month': '12', 'day': '25'}

处理可选组

当某些命名组不匹配时,groupdict 会优雅地处理它们。

optional_groups.py
#!/usr/bin/python

import re

text = "Name: John"
pattern = re.compile(r'Name: (?P<first>\w+)(?: (?P<middle>\w+))?(?: (?P<last>\w+))?')

match = pattern.search(text)
if match:
    print(match.groupdict())

此模式具有可选的中间名和姓氏组。当它们不匹配时,它们会出现在字典中,值为 None

使用默认值

我们可以使用 default 参数为未匹配的组指定默认值。

default_values.py
#!/usr/bin/python

import re

text = "Temperature: 25C"
pattern = re.compile(r'Temperature: (?P<value>\d+)(?P<unit>[CF])?')

match = pattern.search(text)
if match:
    print("Without default:", match.groupdict())
    print("With default:", match.groupdict(default='F'))

此处,unit 组是可选的。如果没有默认值,则为 None。使用 default='F',未匹配的单位默认为华氏度。

组合命名组和未命名组

groupdict 仅包含命名组,忽略未命名的捕获组。

mixed_groups.py
#!/usr/bin/python

import re

text = "Version 3.9.1 released"
pattern = re.compile(r'Version (\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)')

match = pattern.search(text)
if match:
    print("All groups:", match.groups())
    print("Named groups:", match.groupdict())

第一个组是未命名的,因此它出现在 groups 中,但不出现在 groupdict 中。只有 minor 和 patch 出现在字典中。

嵌套组字典

对于复杂的模式,groupdict 可以创建嵌套的数据结构。

nested_groups.py
#!/usr/bin/python

import re

text = "Coordinates: (40.7128, -74.0060)"
pattern = re.compile(
    r'Coordinates: \((?P<lat>-?\d+\.\d+), (?P<lon>-?\d+\.\d+)\)'
)

match = pattern.search(text)
if match:
    coords = match.groupdict()
    print(f"Latitude: {coords['lat']}, Longitude: {coords['lon']}")
    print("Full dictionary:", coords)

这会将纬度和经度提取到字典中,从而可以轻松地按名称访问这些值。输出显示了个人访问和完整字典。

具有多个命名组的高级模式

这是一个更复杂的示例,其中日志行中包含多个命名组。

log_parser.py
#!/usr/bin/python

import re

log_line = "2023-04-20 14:35:22 ERROR [main] App crashed: NullPointerException"
pattern = re.compile(
    r'(?P<date>\d{4}-\d{2}-\d{2}) '
    r'(?P<time>\d{2}:\d{2}:\d{2}) '
    r'(?P<level>\w+) '
    r'\[(?P<thread>\w+)\] '
    r'(?P<message>.*)'
)

match = pattern.search(log_line)
if match:
    log_data = match.groupdict()
    print("Log entry components:")
    for key, value in log_data.items():
        print(f"{key:>8}: {value}")

此模式使用命名组将日志行分解为其组件。 groupdict 方法创建日志条目的结构化表示形式。

最佳实践

使用 Match.groupdict 时,请遵循以下最佳实践

性能注意事项

由于组已经在匹配期间被捕获,因此 groupdict 方法的开销最小。但是,创建字典确实需要一些内存分配。

对于只需要特定组的性能关键型代码,直接使用 group(name) 访问它们可能比使用 groupdict 稍快一些。

来源

Python Match.groupdict() 文档

本教程涵盖了 Python Match.groupdict 方法的基本方面。使用命名组及其字典表示形式可以使您的正则表达式代码更具可读性和可维护性。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。到目前为止,我已经撰写了 1,400 多篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出所有 Python 教程