Parsing and generating JSON

前端 未结 3 533
囚心锁ツ
囚心锁ツ 2021-02-04 11:15

Mathematica\'s list of built-in formats is pretty extensive; however, JSON is not on that list. Is there an existing solution for generating and parsing JSON in Mathematica, or

相关标签:
3条回答
  • 2021-02-04 11:38

    As of Mathematica 8, JSON is a built-in format supporting both Import and Export.

    0 讨论(0)
  • 2021-02-04 11:40

    UPDATE: As noted in Pillsy's answer, JSON is a built-in format for Import and Export as of Mathematica 8: http://reference.wolfram.com/mathematica/ref/format/JSON.html. But, as discussed in the comments, the following seems to be a more robust solution as of Mathematica 10.4.1:

    WARNING: This involves doing an eval (ToExpression) so don't use this to parse strings from untrusted sources.

    First, a really quick-and-dirty partial solution to JSON parsing would be this:

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

    Ie, just replace square brackets with curly braces and colons with arrows and then eval it. All that remains is to not do those substitutions inside of strings. (Also need a few more substitutions for null, true, false, and scientific notation.)

    There's probably a more elegant solution to the not-within-strings problem, but the first thing to come to mind is to do substitutions like "{"->"(*MAGICSTRING*){" and then, after the eval (when comments outside of strings will have disappeared), reverse those substitutions. (PS: Coming back to this later, I'm actually pretty pleased with the cleverness of that, and it seems to be perfectly robust. Magic strings FTW!)

    That's slightly easier said than done but the following JSON parser seems to work:

    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 and eval are convenience functions. Simply cat = ToString would work in this case but I like this more general version that concatenates all its arguments into a string.).

    Finally, here's a function to generate JSON (which does need the more general cat, as well as another utility function for displaying numbers in a JSON-appropriate way):

    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], "\""->"\\\""] <> "\""
    
    0 讨论(0)
  • 2021-02-04 11:55

    This guy has a clever example of parsing JSON code in Mathmatica

    0 讨论(0)
提交回复
热议问题