如何返回匹配某些文本的正则表达式?

Dav*_*ave 5 python regex python-3.x

Javascript正则表达式问题的答案返回匹配的正则表达式的部分是"否,因为编译破坏了正则表达式文本和匹配逻辑之间的关系."

但Python会保留Match Objects,并re.groups()返回触发匹配的特定组.将每个组的正则表达式文本保留为匹配对象的一部分并返回它应该很简单,但似乎没有这样做的调用.

import re

pat = "(^\d+$)|(^\w+$)|(^\W+$)"
test = ['a', 'c3', '36d', '51', '29.5', '#$%&']
for t in test:
    m = re.search(pat, t)
    s = (m.lastindex, m.groups()) if m else ''
    print(str(bool(m)), s)
Run Code Online (Sandbox Code Playgroud)

返回:

True (2, (None, 'a', None))
True (2, (None, 'c3', None))
True (1, ('51', None, None))
False
True (3, (None, None, '#$%&'))
Run Code Online (Sandbox Code Playgroud)

编译器显然知道这种模式中有三个组.有没有办法在正则表达式中提取每个组中的子模式,例如:

>>> print(m.regex_group_text)

('^\d+$', '^\w+$', '^\W+$')
Run Code Online (Sandbox Code Playgroud)

是的,可以编写自定义模式解析器,例如拆分"|" 对于这种特殊的模式.但是,使用re编译器对每个组中文本的理解会更容易,更可靠.

jbn*_*dlr 5

如果索引不够并且您绝对需要知道正则表达式的确切部分,则可能没有其他可能性,只能自己解析表达式的组.

总而言之,这没什么大不了的,因为您只需计算开始和结束括号并记录其索引:

def locateBraces(inp):
    bracePositions = []
    braceStack = []
    depth = 0
    for i in range(len(inp)):
        if inp[i] == '(':
            braceStack.append(i)
            depth += 1
        if inp[i] == ')':
            bracePositions.append((braceStack.pop(), i))
            depth -= 1
            if depth < 0:
                raise SyntaxError('Too many closing braces.')
    if depth != 0:
        raise SyntaxError('Too many opening braces.')
    return bracePositions
Run Code Online (Sandbox Code Playgroud)

编辑:这个愚蠢的实现只计算开始和结束括号.但是,正则表达式可能包含转义大括号,例如\(,使用此方法将其视为常规的组定义大括号.您可能希望调整它以省略在它们之前具有不均匀反斜杠数的大括号.我把这个问题留给你了;)

使用此功能,您的示例变为:

pat = "(^\d+$)|(^\w+$)|(^\W+$)"
bloc = locateBraces(pat)

test = ['a', 'c3', '36d', '51', '29.5', '#$%&']
for t in test:
    m = re.search(pat, t)
    print(str(bool(m)), end='')
    if m:
        h = bloc[m.lastindex - 1]
        print(' %s' % (pat[h[0]:h[1] + 1]))
    else:
        print()
Run Code Online (Sandbox Code Playgroud)

哪个回报:

True (^\w+$)
True (^\w+$)
True (^\w+$)
True (^\d+$)
False
True (^\W+$)
Run Code Online (Sandbox Code Playgroud)

编辑:要获得您的组列表,当然简单的理解会做:

gtxt = [pat[b[0]:b[1] + 1] for b in bloc]
Run Code Online (Sandbox Code Playgroud)