解析并生成 JSON

发布于 2024-08-28 13:46:15 字数 208 浏览 5 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

尾戒 2024-09-04 13:46:15

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

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

首先,JSON 解析的一个真正快速而肮脏的部分解决方案是这样的:

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

即,只需将方括号替换为大括号,将冒号替换为箭头,然后对其进行评估。
剩下的就是在字符串内部进行这些替换。
(还需要对 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]]

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

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], "\""->"\\\""] <> "\""
┊风居住的梦幻卍 2024-09-04 13:46:15

从 Mathematica 8 开始,JSON 是一种内置格式,支持导入和出口。

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

淡水深流 2024-09-04 13:46:15

这家伙有一个巧妙的解析示例Mathmatica 中的 JSON 代码

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文