为何在JSON.stringify前后调用string.replace会得到不同结果?
为什么JSON.stringify后调用replace无法得到和处理前相同的结果?
这是个很典型的JSON序列化细节问题,我来帮你理清背后的逻辑:
核心差异:原始字符串 vs JSON.stringify后的字符串
先看你的代码里两个阶段的字符串本质区别:
- 初始的
str里的\n是实际的换行符(ASCII 0x0A字符),是单个字符; - 经过
JSON.stringify(str)处理后,原来的换行符被转成了两个字符的组合:反斜杠(\)+ 字母n,也就是字符串字面量里的\\n。
JSON.stringify对字符串做了哪些处理?
JSON的语法规则要求字符串中的特殊字符必须被转义,所以JSON.stringify会对输入字符串执行以下关键操作:
- 转义所有JSON规范中的特殊字符:包括换行符
\n、回车符\r、制表符\t、双引号"、反斜杠\等,把它们替换成对应的JSON转义序列(比如\n→\\n,"→\"); - 给整个字符串包裹一层双引号,作为JSON字符串的标识;
- 对于超出ASCII范围的字符,会转成
\uXXXX格式的Unicode转义序列(如果需要的话)。
举个直观的例子,你的初始字符串:
let str = "some long string\nwith line\nbreaks";
经过JSON.stringify后,实际得到的字符串是:
"\"some long string\\nwith line\\nbreaks\""
你通过console.log看到的输出是"some long string\nwith line\nbreaks",这是控制台的显示优化——实际字符串里的\n是转义后的\\n,并不是真正的换行符。
为什么replace的结果不一样?
- 第一次调用
str.replace(/\n/g,'')时,正则/\n/g匹配的是实际的换行符,所以能精准找到所有换行并替换; - 第二次调用时,字符串里已经没有实际的换行符了,只有
\\n(即\和n两个字符),/\n/g自然匹配不到任何内容,所以替换没有效果。如果要替换这些转义后的换行序列,你需要用匹配\\n的正则:console.log(str.replace(/\\n/g,''))
验证小技巧
你可以把字符串拆成单个字符数组来直观看到差异:
let str = "some long string\nwith line\nbreaks"; console.log("原始字符串的字符列表:", [...str]); // 能看到其中的"\n"字符 let strAfter = JSON.stringify(str); console.log("stringify后的字符列表:", [...strAfter]); // 能看到"\\"和"n"的组合,还有转义的双引号
内容的提问来源于stack exchange,提问作者Farrukh Normuradov
相关产品推荐
相关产品推荐

