Parsing and generating JSON

守給你的承諾、 提交于 2019-12-03 10:19:40

问题


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 are we going to have to roll our own solution?


回答1:


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], "\""->"\\\""] <> "\""



回答2:


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




回答3:


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



来源:https://stackoverflow.com/questions/2633003/parsing-and-generating-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!