关于json数据中的多反斜杆转译--StringEscapeUtils.unescapeJava(踩过的坑)
一、需求
现有一个字符串str
String str = "{\\\"name\\\":\\\"spy\\\",\\\"id\\\\":\\\"123456\\\"}";
String params = "{\"sJson\":\"{\\\"operationtype\\\":1,\\\"content\\\":{\\\"senderid\\\":438,\\\"sendername\\\":\\\"许峰\\\",\\\"receiverid\\\":\\\"220\\\",\\\"receivername\\\":\\\"邓强 \\\",\\\"mtitle\\\":\\\"test\\\",\\\"mcontent\\\":\\\"test\\\",\\\"attlist\\\":[]}}\"}";
System.out.println("str = " + str);
System.out.println("params = " + params);
在控制台的输出为:
str = {\"name\":\"spy\",\"id\":\"123456\"}
params =
{"sJson":"{\"operationtype\":\"1\",\"content\":{\"senderid\":\"438\",\"sendername\":\"许峰\",\"receiverid\":\"220\",\"receivername\":\"邓强\",\"mtitle\":\"test\",\"mcontent\":\"test\",\"attlist\":[]}}"}
目标:1、将str转化为标准的json格式串str1,以调用JsonUtil的方法,将字符串转为map。即目标str1为:
str1 = {"name":"spy","id":"123456"}
2、将
params
转化为标准的json格式串
params
,以调用JsonUtil的方法,将字符串转为map。即目标str1为:
{"sJson":"{\"operationtype\":\"1\",\"content\":{\"senderid\":\"438\",\"sendername\":\"许峰\",\"receiverid\":\"220\",\"receivername\":\"邓强\",\"mtitle\":\"test\",\"mcontent\":\"test\",\"attlist\":[]}}"}
二、实现方法
错误实现方法:
param = param.replaceAll("\\\\",",");
param = param.replaceAll(",,,",",");
param = param.replaceAll(",,",",");
param = param.replaceAll(",","\\\\");
因为一直没办法将\\\替换成功,在replaceAll中\\\\表示一个反斜杆 \\\\\\还是一个反斜杠,所以这种转译是失败的,我找到一个java内置工具包,可以实现自动转译,如下:
1. 使用 StringEscapeUtils中的转义与反转义
apache工具包common-lang中有一个很有用的处理字符串的工具类,其中之一就是StringEscapeUtils。利用它可方便地进行html、xml、java等的转义与反转义。
String str = "{\\\"name\\\":\\\"spy\\\",\\\"id\\\\":\\\"123456\\\"}";
System.out.println("原始 str = " + str);
String str1 = StringEscapeUtils.unescapeJava(str);
System.out.println("目标 str1 = " + str1);
//对应方法的StringEscapeUtils.escapeJava(str1);
//可将str1转义回str
控制台输出:
原始 str = {\"name\":\"spy\",\"id\":\"123456\"}
目标 str1 = {"name":"spy","id":"123456"}
2. 使用Java的replaceAll方法
String str1 = str.replaceAll("\\\\","");
//控制台str1的输出为:{"name":"spy","id":"123456"}
三、Java 的replaceAll 内涵解析
使用Java的replaceAll(String regex, String replacement)函数,即用replacement替换所有的regex匹配项,regex是一个正则表达式,replacement是字符串。
String str = "{\\\"name\\\":\\\"spy\\\",\\\"id\\\\":\\\"123456\\\"}";
(1)对于串str,Java将其进行转义,\\ 表示 \ ,\” 表示 ” ,故而在Java内存中即为:
{\”name\”:\”spy\”,\”id\”:\”123456\”},然而,我们的目标是 {“name”:”spy”,”id”:”123456”},即将转义字符 \ 替换为空。
(2)Java的replaceAll(String regex, String replacement)函数,第一个参数是一个正则表达式。在正则表达式中的“\”与后面紧跟的那个字符构成一个转义字符,代表着特殊的意义,比如”\n”表示换行符等。所以,如果要在正则表达式中表示一个反斜杠\,则应当用\\表达 。但参数regex 首先会经过Java的一次转义,若想表达两个反斜杠 \\,则需四个反斜杠。
综上所述:replaceAll 的第一个参数是正则表达式,故而要经过两次转义,一次Java、一次正则。因此就需要四个反斜杠才可以匹配一个反斜杠。故而,替换一个反斜杠为空的replaceAll的代码即为:
str1 = str.replaceAll("\\\\","");
四、补充说明
String的replaceAll 同Matcher.replaceAll. 如下是String的repalceAll的源码实现。
public String repalceAll(String expr,String substitute){
return Pattern.compile(expr).matcher(this).replaceAll(substitute);
}
大家可以注意到Pattern.compile(expr)的参数是正则表达式。故而:
错误写法(运行报错):
String tmp = Pattern.compile("\\").matcher("h\\").replaceAll("ello");
正确写法:
String tmp = Pattern.compile("\\\\").matcher("h\\").replaceAll("ello");
//输出为hello
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!