java中如何忽略字符串中的转义字符--转载

本文介绍了解决跨语言环境中JSON格式数据中的Unicode字符显示不正确的问题。通过使用Apache Commons Lang库中的StringEscapeUtils工具类,成功将字符串中的Unicode转义序列转换为中文字符。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

原文地址:http://my.oschina.net/u/1010578/blog/366252

起因

    这几天工作上需要跟另一个同事联调rest接口,我这边是java他是php,返回报文是json格式。接口调用成功后,输出返回的报文中有类似“\u79fb\u52a8\u4e92\u8054\u7f51\u5e94\u7528 ”的Unicode字符,有点纳闷,记得java是会自动转换Unicode字符为中文才对。

    通过断点debug一看,发现返回的报文在程序中被转换为“\u79fb\u52a8\u4e92\u8054\u7f51\u5e94\u7528”,两个反斜杠表示字符‘\’,所以输出的不是Unicode对应的中文,而是“像Unicode”的字符串了。

解决方案

    只要把得到的报文中的“\”换成“\”,我想就能正常地将Unicode输出成中文了,首先想到的是使用字符串的replaceAll()方法。使用replaceAll(“\\“,“\“),但是发现输出结果没有任何变化。 
查了下API文档,replaceAll()方法的定义是:

public String replaceAll( String regex,String replacement)  ;

    也就是第一个参数指的是正则表达式,所以“\\”用正则表达式的方式来看,匹配的是字符串中的两个\字符,而不是java中的‘\’转义符。换句话说,就是regex参数作为正则表达式查找的源字符串是已经转义过的“\u79fb\u52a8\u4e92\u8054\u7f51\u5e94\u7528”,而不是转义前的“\\u79fb\\u52a8\\u4e92\\u8054\\u7f51\\u5e94\\u7528”,所以replaceAll(“\\“,“\“)自然没效果了。

    后来在StackOverFlow上找到一个忽略转义的工具类, org.apache.commons.lang.StringEscapeUtils ,里面有忽略各种语言的转义符号的方法,既好用也便于理解,就直接拿来用了。 
其中unescapeJava(String s)方法是来处理java转义字符的,可以将字符串中的 “\”转换为 “\”,“'”转换为“'”等。通过这个方法处理以上字符串,刚好能够满足我的需求。

public class Test(){

    public static void main(String[] args) {
        String s = "\\u79fb\\u52a8\\u4e92\\u8054\\u7f51\\u5e94\\u7528";
        String s2 = StringEscapeUtils.unescapeJava(s);
        System.out.println(s);
        System.out.println(s2);

    }

}

输出结果:  
\u79fb\u52a8\u4e92\u8054\u7f51\u5e94\u7528
移动互联网应用

    附上unescapeJava()方法处理转义字符的相关源码,便于理解。

public static void unescapeJava(Writer out, String str) throws IOException {
    if(out == null) {
        throw new IllegalArgumentException("The Writer must not be null");
    } else if(str != null) {
        int sz = str.length();
        StrBuilder unicode = new StrBuilder(4);
        boolean hadSlash = false;
        boolean inUnicode = false;

        for(int i = 0; i < sz; ++i) {
            char ch = str.charAt(i);
            if(inUnicode) {
                unicode.append(ch);
                if(unicode.length() == 4) {
                    try {
                        int nfe = Integer.parseInt(unicode.toString(), 16);
                        out.write((char)nfe);
                        unicode.setLength(0);
                        inUnicode = false;
                        hadSlash = false;
                    } catch (NumberFormatException var9) {
                        throw new NestableRuntimeException("Unable to parse unicode value: " + unicode, var9);
                    }
                }
            } else if(hadSlash) {
                hadSlash = false;
                switch(ch) {
                    case '\"':
                        out.write(34);
                        break;
                    case '\'':
                        out.write(39);
                        break;
                    case '\\':
                        out.write(92);
                        break;
                    case 'b':
                        out.write(8);
                        break;
                    case 'f':
                        out.write(12);
                        break;
                    case 'n':
                        out.write(10);
                        break;
                    case 'r':
                        out.write(13);
                        break;
                    case 't':
                        out.write(9);
                        break;
                    case 'u':
                        inUnicode = true;
                        break;
                    default:
                        out.write(ch);
                }
            } else if(ch == 92) {
                hadSlash = true;
            } else {
                out.write(ch);
            }
        }

        if(hadSlash) {
            out.write(92);
        }

    }
}
 
 
### Java字符串特殊字符转义的方法 在 Java 中,对于字符串中的特殊字符进行转义主要通过使用反斜杠 `\` 来实现。然而,在实际编写代码时需要注意的是,由于反斜杠本身就是一个转义字符,所以在表示单个反斜杠时需要写成 `\\`[^1]。 #### 使用反斜杠进行基本转义 一些常见的转义序列如下: | 序列 | 描述 | | --- | --- | | `\t` | 制表符 | | `\n` | 新行 (换行) | | `\r` | 回车 | | `\"` | 双引号 | | `\'` | 单引号 | 例如,如果想要在一个字符串中包含双引号,则可以这样定义该字符串: ```java String quote = "He said \"Hello World\""; System.out.println(quote); ``` 这段代码会打印出:`He said "Hello World"` #### 正则表达式中的双重转义 当涉及正则表达式的构建时,情况变得更加复杂。因为不仅有 Java 字符串本身的转义需求,还有正则表达式内部的转义逻辑。比如要匹配文件路径分隔符(即反斜杠),就需要四重反斜杠来完成这一操作——两个用来告诉编译器这是个字面意义上的反斜杠;另外两个则是为了使正则引擎识别它为一个普通的反斜杠而不是特殊的控制符号。 ```java // 匹配 Windows 文件路径中的反斜杠 Pattern pattern = Pattern.compile("\\\\"); Matcher matcher = pattern.matcher("C:\\Windows"); while(matcher.find()){ System.out.println("Found a backslash at position: "+matcher.start()); } ``` #### URL 编码作为另一种形式的转义 除了上述提到的方式外,URL 编码也是一种重要的转义机制,特别是在网络请求场景下。Java 提供了多种方式来进行 URL 编解码工作,其中一种简单有效的方法就是利用 `Uri.encode()` 函数[^2]。 ```java public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String url = "http://www.example.com/search?q=java programming"; // 对 URL 中的特殊字符进行编码 String encodedUrl = Uri.encode(url); Log.d(TAG, "原始 URL:" + url); Log.d(TAG, "编码后的 URL:" + encodedUrl); } } ``` 此段代码展示了如何将含有空格和其他可能引起解析错误的字符转换为其对应的百分比编码形式,从而确保整个链接能够被正确传输和解释。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值