确实似乎没有更好的方法来做到这一点,但这里有另一种方法,类似于这个另一个答案 https://stackoverflow.com/a/48858806/9200529但稍微简单一些。它将起作用,前提是: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
根据您给定的文本和模式,返回{'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
这给出了{'long': 'AAAaoasgosaegnsBBB', 'short': 'AAA'}
为了你的给定。如果指定的组之一根本不匹配,则该组将不会出现在字典中。