LISP:如何使用 cl-json 正确编码斜杠(“/”)?

LISP: how to properly encode a slash ("/") with cl-json?

我有使用 cl-json 库添加一行 {"main" : "build/electron.js"} 到 package.json 文件的代码:

(let ((package-json-pathname (merge-pathnames *app-pathname* "package.json")))
  (let
    ((new-json (with-open-file (package-json package-json-pathname :direction :input :if-does-not-exist :error)
                  (let ((decoded-package (json:decode-json package-json)))
                    (let ((main-entry (assoc :main decoded-package)))                      
                      (if (null main-entry)
                        (push '(:main . "build/electron.js") decoded-package)
                        (setf (cdr main-entry) "build/electron.js"))
                      decoded-package)))))
    (with-open-file (package-json package-json-pathname :direction :output :if-exists :supersede)
      (json:encode-json new-json package-json))
  )
)

代码有效,但结果有一个转义斜线:

"main":"build\/electron.js"

我确信这是一件简单的事情,但无论我尝试输入什么——“//”、“/”、“#//”——我仍然得到转义斜杠。

如何在我的输出中得到一个正常的斜杠?

此外,我不确定是否有一种简单的方法可以让我获得漂亮的打印输出,或者我是否需要编写一个函数来执行此操作;现在输出将整个 package.json 文件打印到一行。

特殊字符

JSON Spec表示"任何字符都可以转义。",但其中一些必须转义:"引号,反向solidus 和控制字符。 链接部分后跟一个语法,在转义字符列表中显示“solidus”(/)。我不认为它在实践中真的很重要(通常不需要转义),但这可以解释为什么库转义这个字符。

如何避免转义

cl-json 依赖于名为 +json-lisp-escaped-chars+ 的内部转义字符列表,即:

(defparameter +json-lisp-escaped-chars+
  '((#\" . #\")
    (#\ . #\)
    (#\/ . #\/)
    (#\b . #\Backspace)
    (#\f . #\)
    (#\n . #\Newline)
    (#\r . #\Return)
    (#\t . #\Tab)
    (#\u . (4 . 16)))
  "Mapping between JSON String escape sequences and Lisp chars.")

该符号没有导出,但您仍然可以使用::在外部引用它。您可以围绕需要使用不同转义字符列表的代码动态重新绑定参数;例如,您可以这样做:

(let ((cl-json::+json-lisp-escaped-chars+
     (remove #\/ cl-json::+json-lisp-escaped-chars+ :key #'car)))
  (cl-json:encode-json-plist '("x" "1/5")))

这会打印:

{"x":"1/5"}