Java中如何替换反斜杠但保留换行符\n?
我需要在Java中将字符串里的\替换为/,但现有代码会把转义后的换行符\n变成/n,导致JSON格式异常。以下是我的代码:
json = "{\"fields\": {" + " \"project\":" + " {" + " \"key\": \"key\"" + " }," + " \"summary\": \"" + paramMap.get("summary")[0] + "\"," + " \"description\": \"" + paramMap.get("description")[0].replaceAll("[\\r]{1}", "").replaceAll("\\n","\\\\n").replace('\\', '/')+ "\"," + " \"reporter\": {" + " \"name\": \"" + reporter.getName() + "\"" + " },"+ " \"issuetype\": {" + " \"id\": \"000000\"" + " }," + something.toString() + somethingelse.toString() + " }" + "}";
示例对比
原始输入字符串:
Lorem ip\sum dolor sit amet ,
consectetur adipiscing elit. Proin et metus eget massa facilisis ultricies sit amet sit amet mi. Donec in hendrerit justo. Ut ut
enim vehicu la metus ullamcorper lacinia sit amet fe ugiat sem. Vivamus t empor eros consequat felis tempus tincidunt. Nullam h endrerit orci dictum dolor volutpat, in maximus lorem imperdiet. Aliquam
tristique nunc nec tellus pretium luctus. Nulla suscipit non magna ac bibendum.
期望输出:
Lorem ip/sum dolor sit amet ,
consectetur adipiscing elit. Proin et metus eget massa facilisis ultricies sit amet sit amet mi. Donec in hendrerit justo. Ut ut
enim vehicu la metus ullamcorper lacinia sit amet fe ugiat sem. Vivamus t empor eros consequat felis tempus tincidunt. Nullam h endrerit orci dictum dolor volutpat, in maximus lorem imperdiet. Aliquam
tristique nunc nec tellus pretium luctus. Nulla suscipit non magna ac bibendum.
实际错误输出:
Lorem ip/sum dolor sit amet , /nconsectetur adipiscing elit. Proin et metus eget massa facilisis ultricies sit amet sit amet mi. Donec in hendrerit justo. Ut ut /nenim vehicu la metus ullamcorper lacinia sit amet fe ugiat sem. Vivamus t empor eros consequat felis tempus tincidunt. Nullam h endrerit orci dictum dolor volutpat, in maximus lorem imperdiet. Aliquam /ntristique nunc nec tellus pretium luctus. Nulla suscipit non magna ac bibendum.
问题出在方法调用顺序:你先把换行符\n转义成了\\n(也就是字符串里的两个字符\和n),然后调用replace('\\', '/')时,会把这个转义出来的\也替换成/,最终变成/n。
调整方法顺序即可解决:先替换原始的反斜杠,再处理换行符的转义。修改后的代码片段如下:
"description\": \"" + paramMap.get("description")[0] .replaceAll("[\\r]{1}", "") // 先去掉回车符 .replace('\\', '/') // 替换原始的\为/ .replaceAll("\\n","\\\\n") // 再把换行符转义成\\n + "\","
逻辑说明
- 先移除回车符
\r,不影响后续处理; - 替换原始字符串中的
\为/,这时候还没处理换行符,不会碰到底层的换行转义; - 最后把换行符
\n转义成\\n,此时生成的\是转义用的,不会被之前的替换逻辑影响,最终JSON里的换行符会保持正确的\n格式,同时原始的反斜杠已经被替换成/。
如果需要更精准的正则匹配(比如只替换单独的\,而不是转义序列里的),也可以用replaceAll实现:
.replaceAll("\\\\(?!n)", "/")
这个正则的意思是:匹配后面不是n的反斜杠,替换为/。不过调整顺序的方法更直观,也更贴合你原有代码的逻辑。
内容的提问来源于stack exchange,提问作者J. Doe

