【问题标题】:Parse string to appropriate variables将字符串解析为适当的变量
【发布时间】:2014-05-23 02:20:55
【问题描述】:
[[{"date":"January 2004"},true,false,100,null,null,true],[{"date":"February 2004"},false,false,99,null,null,true]]

我有一长串来自 javascript 文件的数据,如上所示。是否有可以将其解析为适当数据类型的捷径或库?

如您所见,它是一个包含字典、布尔值、整数和空值的列表。

我的意思是,我可以手动完成此操作,但我认为我无法快速或有效地完成此操作。一定有更好的方法。

【问题讨论】:

  • 那些{括号真的没有闭合}括号吗?
  • 不,我的错。我试图简化完整版。我在上面更正了。
  • 这不就是json吗?不知道为什么它有True/False 而不是true/false

标签: python


【解决方案1】:

相当接近有效的 JSON。唯一无效的是False 应该是falseTrue 应该是true。这可能是转录错误(...是的)


使用json

import json

x = '[[{"date":"January 2004"},true,false,100,null,null,true],[{"date":"February 2004"},false,false,99,null,null,true]]'

json.loads(x)
Out[20]: 
[[{'date': 'January 2004'}, True, False, 100, None, None, True],
 [{'date': 'February 2004'}, False, False, 99, None, None, True]]

【讨论】:

  • macdonjo 说他从 JavaScript 获取输出,所以我想知道他在发布数据时是否将布尔值大写...
  • 是的,你们又找到了我,我将它们大写只是因为我在使用 Python 工作,我并没有想到它会有所作为。是的,它们是小写的! :)
【解决方案2】:

我建议你看看 PyParsing。

http://pyparsing.wikispaces.com/

您还可以查看 Python“scanf”库。

sscanf in Python

如果您只需要使用 Python 内置函数来解决这个问题,我建议您使用带有捕获组的正则表达式。

编辑:嗯,我又看了一遍。你确实说过它来自 JavaScript ......这在我看来就像一个合法的 JSON 数组。我尝试使用json 模块(特别是方法函数json.loads()),但无法解析。

但是! Python 语法接近于 JavaScript 语法。替换一些东西,eval() 可以解析这个,或者ast.literal_eval()。我们需要将true 替换为True,将false 替换为False,将null 替换为Noneast.literal_eval() 才会接受它。

import ast
s = '[[{"date":"January 2004"},True,False,100,null,null,true],[{"date":"February 2004"},False,False,99,null,null,true]]'
s1 = s.replace("true","True").replace("false","False").replace("null","None")
x = ast.literal_eval(s1)
print(x)

上面将打印:

[[{'date': 'January 2004'}, True, False, 100, None, None, True], [{'date': 'February 2004'}, False, False, 99, None, None, True]]

最初我展示了定义变量(如true = True)并使用eval() 来解析它,但当然eval() 是一个潜在的安全漏洞;因此,如果您需要解析可能来自网页或任何其他不受信任的来源的文本,导入ast 并改用ast.literal_eval() 是值得的。

编辑:好的,json 模块可以解析这个;问题是使用True 而不是trueFalse 而不是false。只需使用str.replace() 方法函数修复这些问题,然后json.loads() 即可解析。

我正要发布带有.replace()方法调用的代码片段,这时问题再次更新,大写的TrueFalse变成了普通的合法JSON。

所以我的最终答案:

s = '[[{"date":"January 2004"},true,false,100,null,null,true],[{"date":"February 2004"},false,false,99,null,null,true]]'

import json

x = json.loads(s)
print(x)

打印:

[[{u'date': u'January 2004'}, True, False, 100, None, None, True], [{u'date': u'February 2004'}, False, False, 99, None, None, True]]

【讨论】:

  • 您没有将 eval 参数作为字符串输入。记住,它是一个字符串。
  • @macdonjo 感谢您指出这一点。当我测试它时,它起作用了,但是当我在这里输入它时,我没有把字符串引号。通常我从我的 Python 会话中复制/粘贴,所以我放置了正确的测试代码,但这次我一定不能这样做;我想知道为什么不。
  • 数据来源,来自一个非常流行的网站,不是用户输入的。它只是一个大数据库。所以我想这应该是安全的?
  • 这可能是安全的,但如果你打算使用“eval”技巧,我建议无论如何使用ast.literal_eval()。我将修改我的示例以使用它。但您不妨使用json.loads(),因为它确实是合法的 JSON。
  • Pyparsing 不再托管在 wikispaces.com 上。转至github.com/pyparsing/pyparsing
猜你喜欢
  • 1970-01-01
  • 2015-03-19
  • 2015-02-06
  • 2019-07-24
  • 1970-01-01
  • 2014-06-22
  • 1970-01-01
  • 2015-09-02
相关资源
最近更新 更多