解析并生成JSON

Pil*_*lsy 11 json wolfram-mathematica

Mathematica的内置格式列表相当广泛; 但是,JSON不在该列表中.是否存在用于在Mathematica中生成和解析JSON的现有解决方案,或者我们是否必须推出自己的解决方案?

dre*_*ves 18

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

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

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

ToExpression[StringReplace[json, {"["->"{", "]"->"}", ":"->"->"}]]
Run Code Online (Sandbox Code Playgroud)

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

有可能是一个更好的解决方案为无内弦的问题,而是要想到的第一件事就是做这样换人"{"->"(*MAGICSTRING*){",然后中,eval(当字符串之外的评论将消失),扭转这些换人之后.(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]]
Run Code Online (Sandbox Code Playgroud)

(cat并且eval是便利函数.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], "\""->"\\\""] <> "\""
Run Code Online (Sandbox Code Playgroud)

  • Mathematica 8原则上可能具有JSON的导入功能,但是,它拒绝加载一个简单的小型18 MB .json文件(它永远运行).你的功能就像一个魅力.谢谢. (3认同)
  • 从Mathematica 10.4.1开始,内置的JSON解析失败了非ascii unicode字符串(如"✔"或"ε"),而我6年前的小解决方案仍然像魅力一样.(Pats self on back.) (3认同)