【问题标题】:Extract Python dictionary from string从字符串中提取 Python 字典
【发布时间】:2017-02-09 23:43:20
【问题描述】:

我有一个字符串,里面有有效的 python 字典

data = "Some string created {'Foo': u'1002803', 'Bar': 'value'} string continue etc."

我需要提取那个字典。我尝试使用正则表达式,但由于某种原因 re.search(r"\{(.*?)\}", data) 不起作用。有没有更好的方法提取这个字典?

【问题讨论】:

  • 你从哪里得到字符串?为什么会这样?你能得到更有用的格式吗?
  • @jonrsharpe 为什么对这个问题很重要,所以问题很清楚。
  • 对字典进行子串化,然后使用ast.literal_eval(substr)将其变成字典。
  • 因为你可能有一个XY problem,所以按姿势回答是在浪费你和我们的时间。

标签: python regex django dictionary django-views


【解决方案1】:

来自@AChampion 的建议。

>>> import re
>>> import ast
>>> x = ast.literal_eval(re.search('({.+})', data).group(0))
>>> x
{'Bar': 'value', 'Foo': '1002803'}

所以你要找的模式是re.search('({.+})', data)

您应该使用字符串提取花括号,因此 ast.literal_eval 可以将字符串转换为 python 字典。您也不需要 r 前缀作为捕获组中的 {}() 将按字面意思匹配。

【讨论】:

  • 请注意,由于正则表达式是贪婪的,因此在嵌套 dict 的情况下仍然有效,例如"Some string created {'Foo': u'1002803', 'Bar': 'value', 'Baz': {1:2, 3:4}} string continue etc."。但是,如果字符串中有多个单独的dict,则它会失败。例如"Some string created {'Foo': u'1002803', 'Bar': 'value'} string continue etc. Another dict: {1:2, 3:4}"解析器是处理后一种情况所必需的(或者如果{}可能出现在字符串中的任何其他位置)。
  • @jpmc26 使其非贪婪 (re.findall(r'{.+?}', data)) 应处理 { } 的额外出现。但这会弄乱嵌套字典,因为当它们实际上是更大组的一部分时,它们会被视为不同的出现。所以是的,实际上需要一个解析器来同时处理这两种情况。
  • 顺便说一句,你怎么知道我编辑了这个答案(我只是路过并在我的旧答案中修复了一些错字:))
  • 编辑会碰到问题。我碰巧在首页看到了。甚至没有注意到我发表评论的日期。大声笑
  • @jpmc26:您能否详细说明一下“使用解析器”?我被这样的字符串困住了。我真的很感激一些帮助。 ` 'name: "data dict" id: 2\nv6: false\nstats {\n hosts {\n cnt1: 256\n cnt2: 0\n }\n groups {\n cnt1: 1\n cnt2: 0\ n }\n 关键 {\n cnt1: 1\n cnt2: 0\n }\n main_hosts {\n cnt1: 256\n cnt2: 0\n }\n}\n group_id: "None"' ` 怎么做我从中得到字典列表的字典? stats {hosts: {cnt1: 250, cnt2: 0}, groups: {cnt: 1, cnt2: 0}, etc, etc}
【解决方案2】:

无需使用eval即可解析字典的更好方法:

import re
import json

data = "Some string created {'Foo': '1002803', 'Bar': 'value'} string continue"


dict_object = json.loads(re.search('({.+})', data).group(0).replace("'", '"'))

** 如果要解析的字典包含 unicode 字符串值(引用问题的示例字符串):

dict_object = json.loads(re.search('({.+})', data).group(0).replace("u'", '"').replace("'", '"'))

【讨论】:

  • @MatthewBarlowe 这确实有效,在 Python 3.9.9 中进行了测试。此外,json.loads 比 eval 执行更安全,特别是如果您的字符串可以由可能添加恶意代码的用户填写。
  • @MatthewBarlowe 如果要解析的字典包含 unicode 字符串值(引用原始示例字符串),请尝试一下:dict_object = json.loads(re.search('({.+})' , data).group(0).replace("u'", '"').replace("'", '"'))
  • @Boris 不,OP 示例中的字符串中的 u 不会导致解析错误,应在答案中引用
  • @renzob 应在答案中引用,因为 OP 的字符串包含 u
  • 同意json.loads 是一个更安全、更好的过程,但应该能够处理 OP 的输入。评论已删除并已点赞
【解决方案3】:

您的解决方案有效!

In [1]: import re

In [2]: data = "Some string created {'Foo': u'1002803', 'Bar': 'value'} string continue etc."

In [3]: a = eval(re.search(r"\{(.*?)\}", data).group(0))

In [4]: a
Out[4]: {'Bar': 'value', 'Foo': u'1002803'}

【讨论】:

  • 不必要地使用了eval。 -1
猜你喜欢
  • 2020-12-30
  • 2023-01-13
  • 2017-12-15
  • 2016-06-24
  • 2022-06-10
  • 1970-01-01
  • 2022-11-22
  • 2013-07-02
  • 1970-01-01
相关资源
最近更新 更多