玩弄替换当然是一条复杂的道路 -
该语言确实具有内置的这种转义的解析器 -
更简单的方法是通过 eval 调用传递包含 JSON 的字符串。但是很少需要 eval 并且在大多数情况下应该避免使用 eval ,因为它“不优雅”——如果不是完全不安全的话(但不安全实际上只适用于你无法控制输入数据的情况——甚至它们,ast.literal_eval 而不是普通的@ 987654323@ 可以减轻这种情况)。无论如何,格式还有其他问题会阻止 eval 直接工作 - 例如,最外面的data: 缺少引号。
如果您的文件内容实际上是:
data:{\"data\":[\"Kendrick\",\"Lamar\"]}\n\ndata:{\"data\":[\"David\",\"Bowie\"]}\n\n
它有两个问题:“引用不足”最外面的 data 和
内部数据的“over-scaping”。
在交互式 Python 会话中,使用“原始字符串”标记我可以输入您的示例行,因为它将从文件中读取:
In [263]: a = r"""data:{\"data\":[\"Kendrick\",\"Lamar\"]}\n\ndata:{\"data\":[\"David\",\"Bowie\"]}\n\n"""
In [264]: print(a)
data:{\"data\":[\"Kendrick\",\"Lamar\"]}\n\ndata:{\"data\":[\"David\",\"Bowie\"]}\n\n
所以,要删除一级反斜杠 - Python 有一个“unicode_escape”文本编码,但它只适用于字节对象。然后我们求助于“latin1”编码,因为它提供了“a”中的 unicode 文字到字节的逐字节转换,然后应用 unicode_escape 来删除“\”:
In [266]: b = a.encode("latin1").decode("unicode_escape")
In [267]: print(b, "\n", repr(b))
data:{"data":["Kendrick","Lamar"]}
data:{"data":["David","Bowie"]}
'data:{"data":["Kendrick","Lamar"]}\n\ndata:{"data":["David","Bowie"]}\n\n'
现在很容易解析:
我们在 "\n\n" 处拆分结果字符串,并有一个包含一条记录的列表
(你称之为“数据集”的那些)每个元素。然后我们求助于字符串
操作以摆脱起始"data:",最后,json.load 可以处理剩余部分。
所以:
import json
raw_data = open("mystrangefile.pseudo_json").read()
data = data.encode("latin1").decode("unicode_escape")
records = [json.loads(record.split(":", 1)[-1]) for record in data.split("\n\n")]
“记录”现在应该包含表现良好的 Python 对象字典,您可以放入数据库。 (除非 Pandas 可以提供列到数据库的自动映射,否则这似乎是一个不需要的步骤 - 一个原始的 connection.executemany(""" INSERT ...""", records) 具有适当的开放数据库连接就足够了。
另外,在旁注中,您提到您可以使用 .NET 反序列化程序轻松处理此问题:前提是您的文件没有像您向我们展示的那样损坏 - 没有可能的标准序列化程序知道如何处理这样一个特定的开箱即用的数据格式。但是,如果您实际上更精通另一种语言/技术来做到这一点,您可以只写一个转换器,从损坏的输入到正确编码的文件,并将其用作中间步骤。