查找Python正则表达式中捕获组的数量

55 投票
6 回答
73457 浏览
提问于 2025-04-11 09:18

有没有办法可以确定一个给定的正则表达式中有多少个捕获组?

我想要做到以下几点:

def groups(regexp, s):
    """ Returns the first result of re.findall, or an empty default

    >>> groups(r'(\d)(\d)(\d)', '123')
    ('1', '2', '3')
    >>> groups(r'(\d)(\d)(\d)', 'abc')
    ('', '', '')
    """
    import re
    m = re.search(regexp, s)
    if m:
        return m.groups()
    return ('',) * num_of_groups(regexp)

这让我可以做一些事情,比如:

first, last, phone = groups(r'(\w+) (\w+) ([\d\-]+)', 'John Doe 555-3456')

不过,我不知道怎么实现 num_of_groups。目前我只是绕过这个问题。

编辑:根据 rslite 的建议,我把 re.findall 替换成了 re.search

sre_parse 似乎是最稳健和全面的解决方案,但需要遍历树结构,看起来有点复杂。

MizardX 的正则表达式似乎涵盖了所有情况,所以我决定使用这个。

6 个回答

3

从sre_parse内部的一些内容可能会有帮助。

乍一看,可能类似于下面的内容:

>>> import sre_parse
>>> sre_parse.parse('(\d)\d(\d)')
[('subpattern', (1, [('in', [('category', 'category_digit')])])), 
('in', [('category', 'category_digit')]), 
('subpattern', (2, [('in', [('category', 'category_digit')])]))]

也就是说,统计一下类型为'subpattern'的项目:

import sre_parse

def count_patterns(regex):
    """
    >>> count_patterns('foo: \d')
    0
    >>> count_patterns('foo: (\d)')
    1
    >>> count_patterns('foo: (\d(\s))')
    1
    """
    parsed = sre_parse.parse(regex)
    return len([token for token in parsed if token[0] == 'subpattern'])

注意,我们这里只是在统计根级别的模式,所以最后一个例子只返回1。如果想要改变这个结果,就需要递归地搜索tokens

36
f_x = re.search(...)
len_groups = len(f_x.groups())

当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。

58
def num_groups(regex):
    return re.compile(regex).groups

当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。

撰写回答