68

削除された質問に触発されました。名前付きグループを持つ正規表現が与えられた場合、名前付きキャプチャグループのリストではなく、名前付きキャプチャグループのfindallリストを返すようなメソッドはありますか?dicttuple

与えられた:

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

4 に答える 4

135
>>> 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'}]
于 2012-06-19T15:17:49.570 に答える
14

finditerに切り替えることができます

>>> 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'}
于 2012-06-19T15:19:53.433 に答える
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のフィールドから生成される from another リスト内包表記を構築します。これは次のようになります。groupindex

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

内の各アイテムに対してリストが作成されgroupindex、アイテム fromfindallがタプルの場合、from のグループ番号をgroupindex使用して正しいアイテムが検索されます。それ以外の場合、アイテムは (現存する) 名前付きグループに割り当てられます。

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

最後に、文字列のリストのリストから辞書が作成されます。

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'}]
于 2012-06-19T15:05:39.307 に答える