一个同事正试图解析在另一个系统中生成的json字符串,并遇到了我们无法解释的行为。我在这里用一个非常小的代码示例复制了这个问题:
// running in node >= 8 (tried both 8 and 12)
const str1 = '{ "test": "path\\test" }';
const str2 = '{ "test": "path\\atest" }';
try {
console.log('str1:', JSON.parse(str1));
} catch (e) {
console.log('str1 fail')
}
try {
console.log('str2:', JSON.parse(str2))
} catch (e) {
console.log('str2 fail')
}
str1
将成功解析为所需的{ test: 'path\test' }
格式
str2
将失败。
似乎只有在\\
之后的字符是valid JavaScript escape characters之一时,此命令才能成功
(\ t:在str1
情况下为水平制表符)
预期的行为是将\\
转义为单个\
此行为是否有解释?我们很困惑,不胜感激!
答案 0 :(得分:3)
当您的字符串文字带有两个反斜杠时,这两个反斜杠将被解释为单个文字反斜杠,例如,.length
的{{1}}为5,而不是6。
'\\test'
仅允许在转义 的字符之前使用反斜杠,例如JSON.parse
(水平标签)和t
(换行符)。当您在无法转义的字符(例如n
)前加一个文字反斜杠时,a
会引发错误。 (这与Javascript字符串文字不同,Javascript字符串文字可以不必要地转义了常规字符-例如JSON.parse
等效于const str = '\a'
,并且不会引发错误。)您可以看到JSON here中允许的内容的图示-如第四幅图所示,在'a'
之后,唯一允许的字符是\
或"\/bfnrt
中的一个,每个X是一个十六进制数字。
如果您希望解析对象中的uXXXX
属性的值是字符串test
,后跟文字反斜杠,后跟path
或test
,您在声明字符串文字时需要使用四个反斜杠-首先,使Javascript解释器将其解释为两个文字反斜杠,其次,让atest
解释两个文字反斜杠作为已解析字符串中的单个反斜杠。
JSON.parse
您还可以使用const str1 = '{ "test": "path\\\\test" }';
const str2 = '{ "test": "path\\\\atest" }';
try {
console.log('str1:', JSON.parse(str1));
} catch (e) {
console.log('str1 fail')
}
try {
console.log('str2', JSON.parse(str2))
} catch (e) {
console.log('str2 fail')
}
定义字符串文字,以将字符串中的任何单个反斜杠解释为单个文字反斜杠(而不是转义序列的开头):
String.raw