从 Python 中编译的正则表达式中提取命名组正则表达式模式

use*_*097 6 python regex python-3.x

我有一个包含多个命名组的 Python 正则表达式。但是,如果之前的组匹配,则匹配一组的模式可能会被遗漏,因为似乎不允许重叠。举个例子:

import re
myText = 'sgasgAAAaoasgosaegnsBBBausgisego'
myRegex = re.compile('(?P<short>(?:AAA))|(?P<long>(?:AAA.*BBB))')

x = re.findall(myRegex,myText)
print(x)
Run Code Online (Sandbox Code Playgroud)

产生输出:

[('AAA', '')]
Run Code Online (Sandbox Code Playgroud)

“长”组找不到匹配项,因为“AAA”在为前面的“短”组查找匹配项时已用完。

我试图找到一种允许重叠但失败的方法。作为替代方案,我一直在寻找一种方法来分别运行每个命名组。类似于以下内容:

for g in myRegex.groupindex.keys():
    match = re.findall(***regex_for_named_group_g***,myText)
Run Code Online (Sandbox Code Playgroud)

是否可以为每个命名组提取正则表达式?

最终,我想生成一个字典输出(或类似的),如:

{'short':'AAA',
 'long':'AAAaoasgosaegnsBBB'}
Run Code Online (Sandbox Code Playgroud)

任何和所有建议将不胜感激。

Nat*_*eks 3

确实似乎没有更好的方法来做到这一点,但这是另一种方法,类似于另一个答案类似,但稍微简单一些。它将起作用,前提是:a) 您的模式始终形成为一系列由管道分隔的命名组,并且 b) 命名组模式从不包含命名组本身。

如果您对每种模式的所有匹配感兴趣,以下将是我的方法。参数re.split寻找一个文字管道,后跟(?=<,命名组的开头。它编译每个子模式并使用groupindex属性来提取名称。

def nameToMatches(pattern, string):
    result = dict()
    for subpattern in re.split('\|(?=\(\?P<)', pattern):
        rx = re.compile(subpattern)
        name = list(rx.groupindex)[0]
        result[name] = rx.findall(string)
    return result
Run Code Online (Sandbox Code Playgroud)

根据给定的文本和模式,返回{'long': ['AAAaoasgosaegnsBBB'], 'short': ['AAA']}. 根本不匹配的模式的值将是一个空列表。

如果您只想每个模式匹配一​​次,您可以使其变得更简单:

def nameToMatch(pattern, string):
    result = dict()
    for subpattern in re.split('\|(?=\(\?P<)', pattern):
        match = re.search(subpattern, string)
        if match:
            result.update(match.groupdict())
    return result
Run Code Online (Sandbox Code Playgroud)

这给出了{'long': 'AAAaoasgosaegnsBBB', 'short': 'AAA'}你的给定。如果指定的组之一根本不匹配,则该组将不会出现在字典中。