我有一个像这样的输入字符串:
'{ query: { and: [ { and: [ { _t: "Manifest" }, { or: [ { and: [ { _i: { gt: "53b2616fe4b028359ac3fea4" } } ] } ] }, { _s: "active" } ] }, { ENu_v: { elemMatch: { EOJ_v: { in: [ "*", "Production", "QA " ] } } } } ] }, orderby: { _i: 1 } } '
我想将其更改为字典。
a = '{ query: { and: [ { and: [ { _t: "Manifest" }, { or: [ { and: [ { _i: { gt: "53b2616fe4b028359ac3fea4" } } ] } ] }, { _s: "active" } ] }, { ENu_v: { elemMatch: { EOJ_v: { in: [ "*", "Production", "QA " ] } } } } ] }, orderby: { _i: 1 } } '
json.loads(a)
但是这会引发异常
query
应为"query"
,
and
应为"and"
等等。
所以我想将string
之类的所有字符串更改为"string"
,我该如何实现?
答案 0 :(得分:3)
使用re.sub
:
In [1]: import re
In [2]: text = '{ query: { and: [ { and: [ { _t: "Manifest" }, { or: [ { and: [ { _i: { gt: "53b2616fe4b028359ac3fea4" } } ] } ] }, { _s: "active" } ] }, { ENu_v: { elemMatch: { EOJ_v: { in: [ "*", "Production", "QA " ] } } } } ] }, orderby: { _i: 1 } } '
In [3]: re.sub('(\w+):', r'"\1":', text)
Out[3]: '{ "query": { "and": [ { "and": [ { "_t": "Manifest" }, { "or": [ { "and": [ { "_i": { "gt": "53b2616fe4b028359ac3fea4" } } ] } ] }, { "_s": "active" } ] }, { "ENu_v": { "elemMatch": { "EOJ_v": { "in": [ "*", "Production", "QA " ] } } } } ] }, "orderby": { "_i": 1 } } '
请注意,您必须使用原始字符串文字(或转义\1
作为\\1
)作为替换文本,否则您将无法获得预期的输出。
我假设您的文字不包含“奇怪”的内容,例如:
{a: "some:string"}
;此解决方案不保留"some:string"
){a: "{b : \"hello\"}"}
)如果这些假设不成立,你必须实际解析文本,并且你不能单独使用正则表达式来安全地转换它。
ast
模块和codegen
第三方模块可以轻松操作此类数据。例如,您可以创建一个NodeTransformer
子类,例如:
class QuoteNames(ast.NodeTransformer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._inside_dict = False
def visit_Name(self, node):
if self._inside_dict:
return ast.copy_location(ast.Str(node.id), node)
else:
return node
def visit_Dict(self, node):
self._inside_dict = True
self.generic_visit(node)
self._inside_dict = False
return node
并将其用作:
import ast, codegen
codegen.to_source(QuoteNames().visit(ast.parse(text))
但是,您的示例文本不是语法上有效的文字,因为某些括号不匹配(在您的示例中可能是错误),有一些字符串值缺少结尾引号而您无法使用{{1} }或and
标识符。
如果您可以修复格式以匹配python语法,那么上述解决方案比使用正则表达式的解决方案更强大。但是,如果这不可能,你必须为它编写自己的解析器,或者寻找能够做到这一点的第三方模块。
答案 1 :(得分:1)