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'}]