Java处理生僻字的问题

前几天遇到了生僻字的问题。很有意思。在不同的平台上显示的字符不一样,有些是方块有些是?有些干脆就是一个表情图标。
检查了编码没有问题,是UTF-8。

研究了一下最终发现了原因。
出错的字符,落到了UNICODE的私人造字区里面,参考如下。
http://jicheng.tw/hanzi/unicode.html
不同的系统/字体,不能保证私人造字区的一致性。
自己写了段测试代码,发现目前Unicode Base区,扩展ABCD均没有问题,唯独私人造字区不行。

解决方法也比较简单,显示字符之前进行检测就行了,如果发现客户姓名里面有私人造字区的字,那么不显示“姓名,您好”而是显示“亲爱的客户,您好”。

代码如下。注意,在Unicode扩展区,一个字符是由两个\u 表示的。也就是说String类的标准方法charAt等等不适用了,要采用codePointAt, codePointCount来进行字符的相关操作。

public class RareCharacterUtility {

    public static boolean containsUserDefinedUnicode(String string) {
        if (string == null) {
            throw new NullPointerException("Stirng must be non-null");
        }
        int[] code = toCodePointArray(string);
        //  U+E000..U+F8FF
        for (int c : code) {
            if (c >= '\ue000' && c <= '\uf8ff') {
                return true;
            }
        }
        return false;
    }

    static int[] toCodePointArray(String str) {
        int len = str.length();
        int[] acp = new int[str.codePointCount(0, len)];

        for (int i = 0, j = 0; i < len; i = str.offsetByCodePoints(i, 1)) {
            acp[j++] = str.codePointAt(i);
        }
        return acp;
    }

    static String toHex(int[] chars) {
        String r = "[";
        for (int i=0; i<chars.length; i++) {
            if (r.length() > 1) {
                r += ",";
            }
            r += Integer.toHexString(chars[i]);
        }
        r += "]";
        return r;
    }

    public static void main(String[] argu) {
        String rr = ("\u5f20\ue0bf\uD86C\uDE70\uD840\uDC10\uD86D\uDF44\uD87E\uDCAC\u9fc6");
        System.out.println("Unicode = " + toHex(toCodePointArray(rr)));

        boolean r = (containsUserDefinedUnicode(rr));
        System.out.println("Test result = " + r + " should be true");
    }
}
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值