字符被转义成JSON怎么转回来?一篇文章彻底搞懂JSON反序列化与字符反转义
在开发中,我们经常遇到字符串被转义成JSON格式的情况——比如反斜杠\
、引号、换行符\n
等前面多了一个\
,导致字符串无法直接使用,本文将从“为什么会被转义”出发,详细拆解JSON转义的底层逻辑,并提供多种编程语言中“反转义”的实操方法,帮你彻底解决字符转义问题。
先搞懂:为什么字符串会被转义成JSON?
要解决“转义后怎么转回来”,得先明白为什么会被转义,JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,其核心设计原则是“用文本结构表示数据,且必须保证格式无歧义”,为了让字符串中的特殊字符不破坏JSON的结构,JSON规范要求对这些字符进行“转义”——即在前面加反斜杠\
,将其转换为“字面量”而非“语法符号”。
常见的JSON转义字符
下表是JSON规范中必须转义的特殊字符及其转义后的形式:
原字符 | 转义后的形式 | 说明 |
---|---|---|
\" |
双引号(用于包裹字符串,若字符串内出现双引号,必须转义) | |
\ |
\\ |
反斜杠(JSON转义符本身,需转义) |
\/ |
正斜杠(虽然不强制转义,但JSON规范允许转义,部分场景会自动处理) | |
\b |
\\b |
退格符(Backspace,ASCII码为8) |
\f |
\\f |
换页符(Form Feed,ASCII码为12) |
\n |
\\n |
换行符(Line Feed,ASCII码为10) |
\r |
\\r |
回车符(Carriage Return,ASCII码为13) |
\t |
\\t |
制表符(Tab,ASCII码为9) |
\uXXXX |
\\uXXXX |
Unicode字符(如\u4e2d 表示“中”) |
转义场景示例
假设我们有一个字符串:"He said: "Hello, world!\nI'm here."
其中包含双引号、换行符\n
,若直接存为JSON字符串,会被转义为:
"He said: \"Hello, world!\\nI'm here.\"
这里的\
和、\n
都是转义后的结果,目的是让JSON解析器能正确识别字符串的边界和内容,而不是误将中间的当作字符串结束符。
核心方法:如何将转义的JSON“转回来”?
“转回来”的本质是反转义(Unescape)——将转义后的字面量还原为原始字符,根据使用场景(如直接处理字符串、通过JSON库解析),可分为两类方法:JSON库自动解析和手动反转义函数。
方法1:用JSON库自动解析(推荐,最安全)
核心逻辑:几乎所有编程语言的JSON库都内置了“解析”功能,能自动识别并反转义JSON字符串中的转义字符,我们只需将转义后的字符串作为JSON解析的输入,库会自动还原原始数据。
示例:Python
假设转义后的JSON字符串为:json_str = '{"name": "Tom", "msg": "He said: \\"Hello\\", \\"world!\\""}'
使用json.loads()
解析,会自动反转义:
import json json_str = '{"name": "Tom", "msg": "He said: \\"Hello\\", \\"world!\\""}' data = json.loads(json_str) # 自动解析并反转义 print(data["msg"]) # 输出:He said: "Hello", "world!"
示例:JavaScript(Node.js/浏览器)
转义后的JSON字符串:jsonStr = '{"name": "Tom", "msg": "He said: \\"Hello\\", \\"world!\\""}'
使用JSON.parse()
解析:
const jsonStr = '{"name": "Tom", "msg": "He said: \\"Hello\\", \\"world!\\""}'; const data = JSON.parse(jsonStr); // 自动反转义 console.log(data.msg); // 输出:He said: "Hello", "world!"
示例:Java
转义后的JSON字符串:String jsonStr = "{\"name\": \"Tom\", \"msg\": \"He said: \\\"Hello\\\", \\\"world!\\\"\"}";
使用Gson
或Jackson
解析(以Gson为例):
import com.google.gson.Gson; public class Main { public static void main(String[] args) { String jsonStr = "{\"name\": \"Tom\", \"msg\": \"He said: \\\"Hello\\\", \\\"world!\\\"\"}"; Gson gson = new Gson(); Data data = gson.fromJson(jsonStr, Data.class); // 自动解析并反转义 System.out.println(data.msg); // 输出:He said: "Hello", "world!" } } class Data { String name; String msg; }
示例:PHP
转义后的JSON字符串:$jsonStr = '{"name": "Tom", "msg": "He said: \"Hello\", \"world!\""}';
使用json_decode()
解析:
$jsonStr = '{"name": "Tom", "msg": "He said: \"Hello\", \"world!\""}'; $data = json_decode($jsonStr, true); // 第二个参数true返回关联数组 echo $data['msg']; // 输出:He said: "Hello", "world!"
方法2:手动反转义函数(特殊场景备用)
如果字符串不是严格的JSON格式(如只是部分转义,或无法用JSON库解析),则需要手动调用反转义函数,不同语言提供了内置或第三方方法:
示例:Python(json
模块的decode
或第三方库)
Python的json
模块主要用于JSON解析,若需手动反转义字符串,可用unicode_escape
编码(但需注意,unicode_escape
会处理所有转义字符,包括\n
、\t
等):
escaped_str = "He said: \\"Hello\\", \\"world!\\"\\nI'm here." # 方法1:用json.loads(推荐,更安全) import json unescaped_str = json.loads(f'"{escaped_str}"') # 用双引号包裹成JSON字符串,再解析 print(unescaped_str) # 输出:He said: "Hello", "world!"\nI'm here. # 方法2:手动处理(不推荐,易遗漏) unescaped_str = escaped_str.replace('\\"', '"').replace('\\\\', '\\').replace('\\n', '\n') print(unescaped_str) # 输出同上
示例:JavaScript(JSON.parse()
或String.prototype.replace()
)
JavaScript中,JSON.parse()
是首选;若需手动处理,可用正则表达式替换:
const escapedStr = 'He said: \\"Hello\\", \\"world!\\"\\nI\'m here.'; // 方法1:JSON.parse(推荐) const unescapedStr = JSON.parse(`"${escapedStr}"`); // 用反引号包裹成JSON字符串 console.log(unescapedStr); // 输出:He said: "Hello", "world!"\nI'm here. // 方法2:手动replace(不推荐) const manualUnescaped = escapedStr.replace(/\\"/g, '"').replace(/\\\\/g, '\\').replace(/\\n/g, '\n'); console.log(manualUnescaped); // 输出同上
示例:Java(StringEscapeUtils
或String
的replace
)
Java中,Apache Commons Lang
库提供了StringEscapeUtils
类,可直接反转义:
import org.apache.commons.text.StringEscapeUtils; public class Main { public static void main(String[] args) { String escapedStr = "He said: \\\"Hello\\\", \\\"world!\\\"\\nI'm here."; String unescapedStr = StringEscapeUtils.unescapeJson(escapedStr); // 反转义JSON字符串 System.out.println(unescapedStr); // 输出:He said: "Hello", "world!"\nI'm here. } }
若无第三方库,可用String
的replace
手动替换(但需注意转义字符的顺序,如先处理\\
再处理\"
):
String escapedStr = "He said: \\\"Hello\\\", \\\"world!\\\"\\nI
还没有评论,来说两句吧...