【问题标题】:Parsing and generating JSON解析和生成 JSON
【发布时间】:2010-04-13 20:34:32
【问题描述】:

Mathematica 的list of built-in formats 相当广泛;但是,JSON 不在该列表中。是否有在 Mathematica 中生成和解析 JSON 的现有解决方案,还是我们必须推出自己的解决方案?

【问题讨论】:

    标签: json wolfram-mathematica


    【解决方案1】:

    更新:如 Pillsy 的回答中所述,JSON 是从 Mathematica 8 开始导入和导出的内置格式:http://reference.wolfram.com/mathematica/ref/format/JSON.html。但是,正如 cmets 中所讨论的,从 Mathematica 10.4.1 开始,以下似乎是更强大的解决方案:

    警告:这涉及执行 eval (ToExpression),因此不要使用它来解析来自不受信任来源的字符串。

    首先,JSON 解析的一个非常快速和肮脏的部分解决方案是这样的:

    ToExpression[StringReplace[json, {"["->"{", "]"->"}", ":"->"->"}]]
    

    即,只需用大括号替换方括号,用箭头替换冒号,然后对其进行评估。 剩下的就是在字符串中进行这些替换。 (还需要对 null、true、false 和科学记数法进行更多替换。)

    对于 not-within-strings 问题可能有一个更优雅的解决方案,但首先想到的是进行替换,例如 "{"->"(*MAGICSTRING*){",然后在 eval 之后(当字符串外的 cmets 将消失时) ,反转这些替换。 (PS:稍后再谈这个,我其实很满意它的聪明,而且它看起来非常健壮。魔术字符串 FTW!)

    说起来容易做起来难,但下面的 JSON 解析器似乎可以工作:

    cat = StringJoin@@(ToString/@{##})&;          (* Like sprintf/strout in C/C++. *)
    eval = ToExpression;            (* Mathematica function names are too verbose! *)
    
    parseJSON[json_String] := With[{tr = {"["     -> "(*_MAGIC__[__*){",
                                          "]"     -> "(*_MAGIC__]__*)}",
                                          ":"     -> "(*_MAGIC__:__*)->",
                                          "true"  -> "(*_MAGIC__t__*)True",
                                          "false" -> "(*_MAGIC__f__*)False",
                                          "null"  -> "(*_MAGIC__n__*)Null",
                                          "e"     -> "(*_MAGIC__e__*)*10^",
                                          "E"     -> "(*_MAGIC__E__*)*10^"}},
      eval@StringReplace[cat@FullForm@eval[StringReplace[json, tr]], Reverse/@tr]]
    

    cateval 是便利函数。在这种情况下只需 cat = ToString 就可以工作,但我喜欢这个更通用的版本,它将所有参数连接成一个字符串。)。

    最后,这是一个生成 JSON 的函数(它确实需要更通用的 cat,以及另一个以 JSON 适当的方式显示数字的实用函数):

    re = RegularExpression;
    jnum[x_] := StringReplace[
      ToString@NumberForm[N@x, ExponentFunction->(Null&)], re@"\\.$"->""]
    
    genJSON[a_ -> b_]  := genJSON[a] <> ":" <> genJSON[b]
    genJSON[{x__Rule}] := "{" <> cat @@ Riffle[genJSON /@ {x}, ", "] <> "}"
    genJSON[{x___}]    := "[" <> cat @@ Riffle[genJSON /@ {x}, ", "] <> "]"
    genJSON[Null]      := "null"
    genJSON[True]      := "true"
    genJSON[False]     := "false"
    genJSON[x_]        := jnum[x] /; NumberQ[x]
    genJSON[x_]        := "\"" <> StringReplace[cat[x], "\""->"\\\""] <> "\""
    

    【讨论】:

    • @Pillsy,让我们知道这是否适合您,或者您是否发现任何错误或进行改进。您的回答对我非常有帮助,所以我渴望报答!
    • Mathematica 8 原则上可能具有 JSON 的导入功能,但是,它拒绝加载一个简单的 18 mb .json 小文件(它会永远运行)。你的功能就像一个魅力。谢谢。
    • 从 Mathematica 10.4.1 开始,内置 JSON 解析因非 ascii unicode 字符串(如“✔”或“ε”)而失败,而我 6 年前的小解决方案仍然像魅力。 (拍拍自己的背。)
    • 很高兴在内置 JSON 支持中提供内存泄漏(请参阅上面的链接)。但是,我认为可能存在转义反斜杠的错误。试试这个:parseJSON@genJSON[{"path" -> "\\\\server\\data\\file.txt"}]
    • @dreeves 我已经完成了“JSON”导入/导出格式。 “RawJSON”更好,因为它不会泄漏内存并且速度更快。
    【解决方案2】:

    从 Mathematica 8 开始,JSON is a built-in format 支持导入和导出。

    【讨论】:

      【解决方案3】:

      This guy 有一个在 Mathmatica 中解析 JSON 代码的巧妙示例

      【讨论】:

      • 我认为这只是将数字从 JSON 表达式中提取出来,对吧?
      • 是的。这就是 JSON 的优点,很容易解析。
      • 是的,我喜欢 JSON。通过“仅将数字从 JSON expr 中提取出来”,我的意思是与将其完全解析成同构嵌套的 Mathematica 表达式相反。我的回答试图做到这一点。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-03
      • 2018-05-17
      • 2021-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多