Clojure:在 JSON 编码中转义 unicode `\U`
Clojure: Escaping unicode `\U` in JSON encoding
未来读者的后记
- Elm 允许字符串
C:\Users\myuser
中的文字
- 这与 JSON 规范一致
- 我的问题与此无关,但几层转义使问题复杂化。未来的教训:完全生成一个最小的工作示例会发现错误!
原问题
我有一个与 Elm 前端对话的 Clojure 后端。在 Elm 中解码 JSON 值时,我遇到了一个问题。
下面的 \U
表示文字字符反斜杠和 U,就像从文本文件中读取一样。 "\U"
与 Clojure 和 Elm 源代码中的输入相同(\
必须转义)。注意附上 ""
.
问题:编码\U
Elm 字符串解码器不接受转义 "\U"
的文字字符串 \U
。
A blog post 建议获取文字字符串 \U
,这应该在源代码中编码为 "\\U"
,“转义 unicode 转义”。
我要发送给客户端的文字串是C:\Users\myuser
。我更喜欢从服务器向客户端发送有效的JSON。
Clojure 标准库行为
clojure.data.json
不会对包含文字 \U
的字符串执行任何特殊操作。下面的例子显示 \U
和 \m
被同等威胁,反斜杠被转义,后面的字符被忽略。
project.core> (clojure.data.json/write-str "C:\Users\myuser")
"\"C:\\Users\\myuser\""
手动解决方法
临时解决方法是手动转义我需要的字符串:
(defn escape-backslash-u [s]
(clojure.string/replace s "\U" "\\U"))
具体问题
clojure.data.json/write-str
的行为是否正确?据我了解文档,输出应该是有效的 unicode。
- 其他 JSON 图书馆的行为是否相似?
- Elm 的 Json.Decode 拒绝文字字符串
\U
是否正确?
求解进度
- 一位友好的 Clojurians Slack 用户指出了 JSON 标准规范,特别是 7. Strings and 8.2. Unicode characters.
部分
我想你可能走错路了。
你举的字符串"C:\Users\myuser"
是完全没有问题的,它不包含任何Unicode转义序列。它是一个包含 ASCII 字符“C”、“:”、“\”、“U”等的字符串。反斜杠是 Clojure 字符串中的转义字符,因此需要对其本身进行转义以表示文字反斜杠。
在任何情况下,字符串 "C:\Users\myuser"
都可以用 (clojure.data.json/write-str "C:\Users\myuser")
序列化,并且如您所知,这会产生 "\"C:\\Users\\myuser\""
。所有这些看起来都非常简单明了。
打印 "\"C:\\Users\\myuser\""
会导致打印原始字符串 "C:\Users\myuser"
。该字符串被 JSONLint 接受为有效。
我理解为 Elm
beeing 无法将 \"C:\\User...
解码为 "C:\User...
因为它将 \u
解释为转义序列的开始。
我用以下代码尝试了 elm here:
import Html exposing (text)
main =
text "\"c:\\user\\foo\"" // from clojure.data.json/write-str
这又是compiles/runs到
"c:\user\foo"
我觉得不错。
您确定没有其他事情发生(中间件、传输)吗?
未来读者的后记
- Elm 允许字符串
C:\Users\myuser
中的文字 - 这与 JSON 规范一致
- 我的问题与此无关,但几层转义使问题复杂化。未来的教训:完全生成一个最小的工作示例会发现错误!
原问题
我有一个与 Elm 前端对话的 Clojure 后端。在 Elm 中解码 JSON 值时,我遇到了一个问题。
下面的\U
表示文字字符反斜杠和 U,就像从文本文件中读取一样。 "\U"
与 Clojure 和 Elm 源代码中的输入相同(\
必须转义)。注意附上 ""
.
问题:编码\U
Elm 字符串解码器不接受转义 "\U"
的文字字符串 \U
。
A blog post 建议获取文字字符串 \U
,这应该在源代码中编码为 "\\U"
,“转义 unicode 转义”。
我要发送给客户端的文字串是C:\Users\myuser
。我更喜欢从服务器向客户端发送有效的JSON。
Clojure 标准库行为
clojure.data.json
不会对包含文字 \U
的字符串执行任何特殊操作。下面的例子显示 \U
和 \m
被同等威胁,反斜杠被转义,后面的字符被忽略。
project.core> (clojure.data.json/write-str "C:\Users\myuser")
"\"C:\\Users\\myuser\""
手动解决方法
临时解决方法是手动转义我需要的字符串:
(defn escape-backslash-u [s]
(clojure.string/replace s "\U" "\\U"))
具体问题
clojure.data.json/write-str
的行为是否正确?据我了解文档,输出应该是有效的 unicode。- 其他 JSON 图书馆的行为是否相似?
- Elm 的 Json.Decode 拒绝文字字符串
\U
是否正确?
求解进度
- 一位友好的 Clojurians Slack 用户指出了 JSON 标准规范,特别是 7. Strings and 8.2. Unicode characters. 部分
我想你可能走错路了。
你举的字符串"C:\Users\myuser"
是完全没有问题的,它不包含任何Unicode转义序列。它是一个包含 ASCII 字符“C”、“:”、“\”、“U”等的字符串。反斜杠是 Clojure 字符串中的转义字符,因此需要对其本身进行转义以表示文字反斜杠。
在任何情况下,字符串 "C:\Users\myuser"
都可以用 (clojure.data.json/write-str "C:\Users\myuser")
序列化,并且如您所知,这会产生 "\"C:\\Users\\myuser\""
。所有这些看起来都非常简单明了。
打印 "\"C:\\Users\\myuser\""
会导致打印原始字符串 "C:\Users\myuser"
。该字符串被 JSONLint 接受为有效。
我理解为 Elm
beeing 无法将 \"C:\\User...
解码为 "C:\User...
因为它将 \u
解释为转义序列的开始。
我用以下代码尝试了 elm here:
import Html exposing (text)
main =
text "\"c:\\user\\foo\"" // from clojure.data.json/write-str
这又是compiles/runs到
"c:\user\foo"
我觉得不错。
您确定没有其他事情发生(中间件、传输)吗?