受到现在删除的问题的启发;给定一个带有命名组的正则表达式,是否有像findall
这样的方法,它返回一个dict
列表,其中包含指定的捕获组而不是tuple
列表?
假设:
>>> import re
>>> text = "bob sue jon richard harry"
>>> pat = re.compile('(?P<name>[a-z]+)\s+(?P<name2>[a-z]+)')
>>> pat.findall(text)
[('bob', 'sue'), ('jon', 'richard')]
应改为:
[{'name': 'bob', 'name2': 'sue'}, {'name': 'jon', 'name2': 'richard'}]
答案 0 :(得分:84)
>>> import re
>>> s = "bob sue jon richard harry"
>>> r = re.compile('(?P<name>[a-z]+)\s+(?P<name2>[a-z]+)')
>>> [m.groupdict() for m in r.finditer(s)]
[{'name2': 'sue', 'name': 'bob'}, {'name2': 'richard', 'name': 'jon'}]
答案 1 :(得分:9)
你可以切换到发现者
>>> import re
>>> text = "bob sue jon richard harry"
>>> pat = re.compile('(?P<name>[a-z]+)\s+(?P<name2>[a-z]+)')
>>> for m in pat.finditer(text):
... print m.groupdict()
...
{'name2': 'sue', 'name': 'bob'}
{'name2': 'richard', 'name': 'jon'}
答案 2 :(得分:4)
如果您正在使用匹配:
r = re.match('(?P<name>[a-z]+)\s+(?P<name2>[a-z]+)', text)
r.groupdict()
答案 3 :(得分:1)
没有内置的方法可以做到这一点,但是可以通过使用列表推导来实现预期的结果。
[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
的结果,该结果是字符串列表或元组列表(0或1个捕获组导致str
列表)。
对于结果中的每个项目,我们从另一个列表推导构造dict
,该列表推导是从编译模式的groupindex
字段生成的,如下所示:
>>> pat.groupindex
{'name2': 2, 'name': 1}
为groupindex
中的每个项目构建一个列表,如果findall
中的项目是元组,则groupindex
的组号用于查找正确的项目,否则item被分配给(仅存在的)命名组。
[k, i if isinstance(i, str) else i[v-1]]
最后,dict是根据字符串列表构建的。
请注意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'}]