截取中文字符的一些注意事项

小弟在对接业务的时候 要求将数据写入文件,GBK格式,上传,下载也是GBK的。但出现了一种情况,获取文件中一行内容后,截取一段有中文的数据,就会出现    截取结果的长度要大于输入的长度,比如我截取6个字符长度,但实际却截取了8个长度。截取方法是String的subString方法。

仔细查看后才知道,subString的方法是默认将字符都处理成--UCS2字符,所以长度会有变化。

经过一番查找最后得出 ,要截取字符串之前都需要对字符进行处理

 

以下是代码

public static void main(String args[]) throws UnsupportedEncodingException {
       String str = "我ABC。汉DEF";
       System.out.println("-----字符串的字节长度是:"+str.getBytes().length+"-----");

       char[] arr = str.toCharArray();
       //测试isNotChinese方法
       char aaa = '。';
       System.out.println("====第一个字符是否是汉字?"+isNotChinese(aaa)+"==,很明显 不认识中文标点符号===");
       System.out.println("====第二个字符是否是汉字?"+isNotChinese(arr[1])+"=====");
       //汉字个数---测试isChinese方法
       int count = 0;
       for (int i = 0; i < arr.length; i++) {
           char ai = arr[i];
           if(isChinese(ai)){
               count++;
           }
       }
       System.out.println("----判断有几个汉字-----");
       System.out.println(count);
       //截取指定开始位置 和长度的字节,可转换成GBK
       System.out.println(btyeSubstring(str,6,0));



   }

   /**
    * 按照字节对字符串进行截取
    * @param str
    * @param count
    * @param start
    * @return
    * @throws UnsupportedEncodingException
    */
   public static String btyeSubstring(String str,int count,int start) throws UnsupportedEncodingException {
       //串不能为空
       if(null != str && !"".equals(str)){
           //对参数进行字符转换
           str = new String(str.getBytes(),"UTF-8");
           //判断要截取的字节数
           if(count > 0 && count < str.getBytes("UTF-8").length){
               StringBuilder buff = new StringBuilder();
               char c;
               for(int i = start; i < count; i++){
                   //按照需要截取的长度 0-count  进行截取,char类型,按字节截取
                   c = str.charAt(i);
                   buff.append(c);
                   //判断c 是不是汉字,如果是,则截取的长度要缩减1
                   if(isChinese(c)){
                       --count;
                   }
               }
               return new String(buff.toString().getBytes(),"UTF-8");
           }
       }
       return str;
   }

   /**
    * 判断是否是中文相关字符
    * @param c
    * @return
    */
   public static boolean isChinese(char c) {
       Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
       if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
               || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
               || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
               || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
           return true;
       }
       return false;
   }

   /**
    * 判断汉字,不能判断中文符号
    * @param c
    * @return
    */
   public static boolean isNotChinese(char c){
       //0x4E00   0x9FA5是汉字在unicode 16进制编码中的区间值
       return (c >= 0x4E00 &&  c <= 0x9FA5) ? true : false;
   }

 

注意:0x4E00 ,0x9FA5是汉字在unicode 16进制编码中的区间值,判断汉字足够,但判断中文标点就不行了。需要使用Character.UnicodeBlock 指定的属性进行判断。

转载于:https://my.oschina.net/u/2543341/blog/1503333

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值