代码之家  ›  专栏  ›  技术社区  ›  Pillsy

解析和生成JSON

  •  11
  • Pillsy  · 技术社区  · 16 年前

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

    3 回复  |  直到 9 年前
        1
  •  18
  •   dreeves    9 年前

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

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

    首先,对于JSON解析来说,真正快速而肮脏的部分解决方案是:

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

    也就是说,只需用大括号替换方括号,用箭头替换冒号,然后将其eval。 剩下的就是 在字符串内部进行这些替换。 (还需要对空、真、假和科学符号进行更多的替换。)

    对于不在字符串内的问题,可能有一个更优雅的解决方案,但首先要想到的是做如下的替换 "{"->"(*MAGICSTRING*){" 然后,在eval之后(当字符串之外的注释消失时),反转这些替换。 (附言:稍后再谈这个,我真的很满意它的聪明,而且它看起来非常健壮。魔法弦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]]
    

    ( cat eval 是便利功能。简单地 cat = ToString 在这种情况下可以工作,但我喜欢这个更通用的版本,它将所有参数连接成一个字符串)。

    最后,这里有一个生成JSON的函数(它需要更一般的 以及另一个实用程序函数,用于以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], "\""->"\\\""] <> "\""
    
        2
  •  3
  •   Pillsy    15 年前

    从Mathematica 8开始, JSON is a built-in format 支持进出口。

        3
  •  2
  •   Jon W    16 年前

    This guy 在Mathmatica中有一个解析JSON代码的聪明例子