re.findall返回一个命名捕获组的字典?

受到现在被删除的问题的启发; 给定一个带有命名组的正则expression式,是否有像findall这样的方法返回一个dict的列表与命名捕获组而不是一个tuple列表?

鉴于:

 >>> import re >>> text = "bob sue jon richard harry" >>> pat = re.compile('(?P<name>[az]+)\s+(?P<name2>[az]+)') >>> pat.findall(text) [('bob', 'sue'), ('jon', 'richard')] 

应该改为:

 [{'name': 'bob', 'name2': 'sue'}, {'name': 'jon', 'name2': 'richard'}] 

 >>> import re >>> s = "bob sue jon richard harry" >>> r = re.compile('(?P<name>[az]+)\s+(?P<name2>[az]+)') >>> [m.groupdict() for m in r.finditer(s)] [{'name2': 'sue', 'name': 'bob'}, {'name2': 'richard', 'name': 'jon'}] 

你可以切换到finditer

 >>> import re >>> text = "bob sue jon richard harry" >>> pat = re.compile('(?P<name>[az]+)\s+(?P<name2>[az]+)') >>> for m in pat.finditer(text): ... print m.groupdict() ... {'name2': 'sue', 'name': 'bob'} {'name2': 'richard', 'name': 'jon'} 

如果你正在使用匹配:

 r = re.match('(?P<name>[az]+)\s+(?P<name2>[az]+)', text) r.groupdict() 

文档在这里

这样做没有内置的方法,但预期的结果可以通过使用列表parsing来实现。

 [dict([[k, i if isinstance(i, str) else i[v-1]] for k,v in pat.groupindex.items()]) for i in pat.findall(text)] 

友好的格式:

 >>> [ ... dict([ ... [k, i if isinstance(i, str) else i[v-1]] ... for k,v in pat.groupindex.items() ... ]) ... for i in pat.findall(text) ... ] 

我们使用列表理解构造一个列表,迭代findall的结果,它是一个string列表或一个元组列表(0或1个捕获组导致一个str列表)。

对于结果中的每个项目,我们都会从编译模式的groupindex字段生成的另一个列表理解构造一个dict ,如下所示:

 >>> pat.groupindex {'name2': 2, 'name': 1} 

为组groupindex每个项目构造列表,并且如果来自findall的项目是元组,则使用来自组groupindex的组编号来查找正确的项目,否则该项目被分配给(仅存在的)命名组。

 [k, i if isinstance(i, str) else i[v-1]] 

最后,一个字典是从string列表中构build的。

请注意, groupindex仅包含已命名的组,因此在命令dict中将省略非命名的捕获组。

结果是:

 [dict([[k, i if isinstance(i, str) else i[v-1]] for k,v in pat.groupindex.items()]) for i in pat.findall(text)] [{'name2': 'sue', 'name': 'bob'}, {'name2': 'richard', 'name': 'jon'}]