java按字节截取带有汉字的字符串的解法(推荐)

由于接口使用的oracle字段长度为固定字节数,然后传进来的字符串估计比数据库字段的总字节数要大,那么截取小于数据库字节数的字符串。

自己参考网上的例子,整了个递归调用就可以了,因为截取的字符字节长度必须小与数据库的字节长度,即如果最后一个字符为汉字,那么只能去掉往前截取。

/**
   * 判断传进来的字符串,是否
   * 大于指定的字节,如果大于递归调用
   * 直到小于指定字节数 ,一定要指定字符编码,因为各个系统字符编码都不一样,字节数也不一样
   * @param s
   *      原始字符串
   * @param num
   *      传进来指定字节数
   * @return String 截取后的字符串 

   * @throws UnsupportedEncodingException
   */
  public static String idgui(String s,int num)throws Exception{
    int changdu = s.getBytes("UTF-8").length;
    if(changdu > num){
      s = s.substring(0, s.length() - 1);
      s = idgui(s,num);
    }
    return s;
  }

java面试题:

编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。但是要保证汉字不被截半个,如"我ABC"4,应该截为"我AB",输入"我ABC汉DEF",6,应该输出为"我ABC"而不是"我ABC+汉的半个"。

目前很多流行的语言,如C#、Java内部采用的都是 Unicode 16(UCS2)编码,在这种编码中所有的字符都是两个字符,因此,如果要截取的字符串是中、英文、数字混合的,就会产生问题,如下面的字符串:

String s = "a加b等于c,如果a等1、b等于2,那么c等3";

上面的字符串既有汉字,又有英文字符和数字。如果要截取前6个字节的字符,应该是”a加b等",但如果用substring方法截取前6个字符就成了"a 加b等于c"。产生这个问题的原因是将substring方法将双字节的汉字当成一个字节的字符(UCS2字符)处理了。

英文字母和中文汉字在不同的编码格式下,所占用的字节数也是不同的,我们可以通过下面的例子来看看在一些常见的编码格式下,一个英文字母和一个中文汉字分别占用多少字节。

import java.io.UnsupportedEncodingException;  

public class EncodeTest {
  /**
   * 打印字符串在指定编码下的字节数和编码名称到控制台
   *
   * @param s
   *      字符串
   * @param encodingName
   *      编码格式
   */
  public static void printByteLength(String s, String encodingName) {
    System.out.print("字节数:");
    try {
      System.out.print(s.getBytes(encodingName).length);
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    System.out.println(";编码:" + encodingName);
  }  

  public static void main(String[] args) {
    String en = "A";
    String ch = "人";  

    // 计算一个英文字母在各种编码下的字节数
    System.out.println("英文字母:" + en);
    EncodeTest.printByteLength(en, "GB2312");
    EncodeTest.printByteLength(en, "GBK");
    EncodeTest.printByteLength(en, "GB18030");
    EncodeTest.printByteLength(en, "ISO-8859-1");
    EncodeTest.printByteLength(en, "UTF-8");
    EncodeTest.printByteLength(en, "UTF-16");
    EncodeTest.printByteLength(en, "UTF-16BE");
    EncodeTest.printByteLength(en, "UTF-16LE");  

    System.out.println();  

    // 计算一个中文汉字在各种编码下的字节数
    System.out.println("中文汉字:" + ch);
    EncodeTest.printByteLength(ch, "GB2312");
    EncodeTest.printByteLength(ch, "GBK");
    EncodeTest.printByteLength(ch, "GB18030");
    EncodeTest.printByteLength(ch, "ISO-8859-1");
    EncodeTest.printByteLength(ch, "UTF-8");
    EncodeTest.printByteLength(ch, "UTF-16");
    EncodeTest.printByteLength(ch, "UTF-16BE");
    EncodeTest.printByteLength(ch, "UTF-16LE");
  }
} 

运行结果如下:

1.英文字母:A
2.字节数:1;编码:GB2312
3.字节数:1;编码:GBK
4.字节数:1;编码:GB18030
5.字节数:1;编码:ISO-8859-1
6.字节数:1;编码:UTF-8
7.字节数:4;编码:UTF-16
8.字节数:2;编码:UTF-16BE
9.字节数:2;编码:UTF-16LE
10.中文汉字:人
11.字节数:2;编码:GB2312
12.字节数:2;编码:GBK
13.字节数:2;编码:GB18030
14.字节数:1;编码:ISO-8859-1
15.字节数:3;编码:UTF-8
16.字节数:4;编码:UTF-16
17.字节数:2;编码:UTF-16BE
18.字节数:2;编码:UTF-16LE

UTF-16BE和UTF-16LE是UNICODE编码家族的两个成员。UNICODE标准定义了UTF-8、UTF-16、UTF-32三种编码格式,共有UTF-8、UTF-16、UTF-16BE、UTF-16LE、UTF-32、UTF-32BE、UTF-32LE七种编码方案。JAVA所采用的编码方案是UTF-16BE。从上例的运行结果中我们可以看出,GB2312、GBK、GB18030三种编码格式都可以满足题目的要求。下面我们就以GBK编码为例来进行解答。

我们不能直接使用String类的substring(int beginIndex, int endIndex)方法,因为它是按字符截取的。'我'和'Z'都被作为一个字符来看待,length都是1。实际上我们只要能区分开中文汉字和英文字母,这个问题就迎刃而解了,而它们的区别就是,中文汉字是两个字节,英文字母是一个字节。

package com.newyulong.iptv.billing.ftpupload;

import java.io.UnsupportedEncodingException;

public class CutString {
   /**
   * 判断是否是一个中文汉字
   *
   * @param c
   *      字符
   * @return true表示是中文汉字,false表示是英文字母
   * @throws UnsupportedEncodingException
   *       使用了JAVA不支持的编码格式
   */
  public static boolean isChineseChar(char c)
      throws UnsupportedEncodingException {
    // 如果字节数大于1,是汉字
    // 以这种方式区别英文字母和中文汉字并不是十分严谨,但在这个题目中,这样判断已经足够了
    return String.valueOf(c).getBytes("UTF-8").length > 1;
  } 

  /**
   * 按字节截取字符串
   *
   * @param orignal
   *      原始字符串
   * @param count
   *      截取位数
   * @return 截取后的字符串
   * @throws UnsupportedEncodingException
   *       使用了JAVA不支持的编码格式
   */
  public static String substring(String orignal, int count)
      throws UnsupportedEncodingException {
    // 原始字符不为null,也不是空字符串
    if (orignal != null && !"".equals(orignal)) {
      // 将原始字符串转换为GBK编码格式
      orignal = new String(orignal.getBytes(), "UTF-8");//
     // System.out.println(orignal);
     //System.out.println(orignal.getBytes().length);
      // 要截取的字节数大于0,且小于原始字符串的字节数
      if (count > 0 && count < orignal.getBytes("UTF-8").length) {
        StringBuffer buff = new StringBuffer();
        char c;
        for (int i = 0; i < count; i++) {
          System.out.println(count);
          c = orignal.charAt(i);
          buff.append(c);
          if (CutString.isChineseChar(c)) {
            // 遇到中文汉字,截取字节总数减1
            --count;
          }
        }
      //  System.out.println(new String(buff.toString().getBytes("GBK"),"UTF-8"));
        return new String(buff.toString().getBytes(),"UTF-8");
      }
    }
    return orignal;
  } 

  /**
   * 按字节截取字符串
   *
   * @param orignal
   *      原始字符串
   * @param count
   *      截取位数
   * @return 截取后的字符串
   * @throws UnsupportedEncodingException
   *       使用了JAVA不支持的编码格式
   */
  public static String gsubstring(String orignal, int count)
      throws UnsupportedEncodingException {
    // 原始字符不为null,也不是空字符串
    if (orignal != null && !"".equals(orignal)) {
      // 将原始字符串转换为GBK编码格式
      orignal = new String(orignal.getBytes(), "GBK");
      // 要截取的字节数大于0,且小于原始字符串的字节数
      if (count > 0 && count < orignal.getBytes("GBK").length) {
        StringBuffer buff = new StringBuffer();
        char c;
        for (int i = 0; i < count; i++) {
          c = orignal.charAt(i);
          buff.append(c);
          if (CutString.isChineseChar(c)) {
            // 遇到中文汉字,截取字节总数减1
            --count;
          }
        }
        return buff.toString();
      }
    }
    return orignal;
  } 

  /**
   * 判断传进来的字符串,是否
   * 大于指定的字节,如果大于递归调用
   * 直到小于指定字节数
   * @param s
   *      原始字符串
   * @param num
   *      传进来指定字节数
   * @return String 截取后的字符串
   */
  public static String idgui(String s,int num){
    int changdu = s.getBytes().length;
    if(changdu > num){
      s = s.substring(0, s.length() - 1);
      s = idgui(s,num);
    }
    return s;
  }

  public static void main(String[] args) throws Exception{
    // 原始字符串
    String s = "我ZWR爱你们JAVA";
    System.out.println("原始字符串:" + s + " : 字节数是: " + s.getBytes().length); 

/*      System.out.println("截取前1位:" + CutString.substring(s, 1));
      System.out.println("截取前2位:" + CutString.substring(s, 2));
      System.out.println("截取前4位:" + CutString.substring(s, 4)); */
      //System.out.println("截取前12位:" + CutString.substring(s, 12));
      System.out.println("截取前12字节:" + CutString.idgui(s, 11)); 

  }
}

以上这篇java按字节截取带有汉字的字符串的解法(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • java 字符串截取的实例详解

    java 字符串截取的实例详解 题目 在java中,字符串"abcd"与字符串"ab你好"的长度是一样,都是四个字符. 但对应的字节数不同,一个汉字占两个字节. 定义一个方法,按照指定的字节数来取子串. 如:对于"ab你好",如果取三个字节,那么子串就是ab与"你"字的半个,那么半个就要舍弃. 如果取四个字节就是"ab你",取五个字节还是"ab你". 仅考虑GBK和utf-8编码 实例代

  • java 截取字符串(判断汉字)

    复制代码 代码如下: /** * 截取字符串 len为字节长度 * @param str * @param len * @return * @throws UnsupportedEncodingException */ public static String getLimitLengthString( String str,int len){ try{ int counterOfDoubleByte = 0; byte[] b = str.getBytes("gb2312"); if

  • JAVA中截取字符串substring用法详解

    substring public String substring(int beginIndex) 返回一个新的字符串,它是此字符串的一个子字符串.该子字符串始于指定索引处的字符,一直到此字符串末尾. 例如: "unhappy".substring(2) returns "happy" "Harbison".substring(3) returns "bison" "emptiness".substring

  • Java截取字符串的方法

    本文实例讲述了Java截取字符串的方法.分享给大家供大家参考.具体实现方法如下: public static void main(String args[]) { //以该字符第一次出现,开始截取 //String str="abc.def"; //String str="abc.def.sdfsdf.fsdfd.ddddd.ggggg.ttttt"; //String str1=str.substring(str.indexOf(".")+1,

  • Java截取特定两个标记之间的字符串实例

    如有一串字符串: <abcd efg>higklmnopq<rstu vwxyz> java代码如下: public class StringTest { public static void main(String[] args) { String str = "<abcd efg>higklmnopq<rstu vwxyz"; System.out.println(str.substring(str.indexOf(">&q

  • java 实现截取字符串并按字节分别输出实例代码

    java 实现截取字符串并按字节分别输出实例代码 前言: 请编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串.但是要保证汉字不被截半个,如"我ABC"4,应该截为"我AB",输入"我ABC汉DEF"6,应该输出"我ABC",而不是"我ABC"+"汉"字的半个. 2.解析思想 本题容易产生困惑的是中文字符和英文字符如何处理,在这里需要考虑汉字和英文字符的占用字节

  • java中简单的截取分割字符串实例

    目前整理出来三种形式: 可根据实际需要选择使用 String userNameUrl; int beginIndex = 0; int endIndex = 0; userNameUrl = "454512@hongri@4944115455d9591b274648a06303d910de"; /** * 方法一: */ beginIndex = userNameUrl.indexOf("@")+1; endIndex = userNameUrl.lastIndex

  • Java使用正则表达式截取重复出现的XML字符串功能示例

    本文实例讲述了Java使用正则表达式截取重复出现的XML字符串功能.分享给大家供大家参考,具体如下: public static void main(String[] args) throws DocumentException { String s = "<MTCCommand Time=\"2014-03-22\"><Login UserId=\"admin\" UserPasswd=\"123\" />&l

  • java 字符串截取的三种方法(推荐)

    众所周知,java提供了很多字符串截取的方式.下面就来看看大致有几种. 1.split()+正则表达式来进行截取. 将正则传入split().返回的是一个字符串数组类型.不过通过这种方式截取会有很大的性能损耗,因为分析正则非常耗时. String str = "abc,12,3yy98,0"; String[] strs=str.split(","); for(int i=0,len=strs.length;i<len;i++){ System.out.pri

  • java按字节截取带有汉字的字符串的解法(推荐)

    由于接口使用的oracle字段长度为固定字节数,然后传进来的字符串估计比数据库字段的总字节数要大,那么截取小于数据库字节数的字符串. 自己参考网上的例子,整了个递归调用就可以了,因为截取的字符字节长度必须小与数据库的字节长度,即如果最后一个字符为汉字,那么只能去掉往前截取. /** * 判断传进来的字符串,是否 * 大于指定的字节,如果大于递归调用 * 直到小于指定字节数 ,一定要指定字符编码,因为各个系统字符编码都不一样,字节数也不一样 * @param s * 原始字符串 * @param

  • JAVA如何按字节截取字符串

    这篇文章主要介绍了JAVA如何按字节截取字符串,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 public class SubStringTest { @Test public void test() { String s = "北京市丰台区东铁营街道政馨园社区1区1号楼1层"; System.out.println(subString(s, 58)); } public static String subString(String

  • Java使用substring()截取(提取)子字符串

    在 String 中提供了两个截取字符串的方法,一个是从指定位置截取到字符串结尾,另一个是截取指定范围的内容.下面对这两种方法分别进行介绍. 1. substring(int beginIndex) 形式 此方式用于提取从索引位置开始至结尾处的字符串部分.调用时,括号中是需要提取字符串的开始位置,方法的返回值是提取的字符串.例如: String str = "我爱 Java 编程"; String result = str.substring(3); System.out.printl

  • Go语言按字节截取字符串的方法

    本文实例讲述了Go语言按字节截取字符串的方法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: // 按字节截取字符串 utf-8不乱码 func SubstrByByte(str string, length int) string {     bs := []byte(str)[:length]     bl := 0     for i:=len(bs)-1; i>=0; i-- {         switch {         case bs[i] >= 0 &

  • 标题过长使用javascript按字节截取字符串

    做为一个前端开发人员在网页展示中经常会碰到,标题过长,需要截取字符串,用CSS的实现的话各种兼容问题,各种坑. 让后台程序截一下,又各种推托,让后台按字节截一下更是和要了后台老命一样,最后可能只会安字符长度给你截一下,最后不好看,对不齐,还是回头整CSS.调兼容: 有以上有感触的前端同学默默点个赞吧. 最近接触一个项目,后台只提供接口(json),所有页面的数据渲染,数据绑定都都交给了前端.终于,不考虑SEO,页面所有的主动权到偶的手中了,不经意间就碰到字节截取老问题了. 网络上流传一个Java

  • Java使用split截取字符串过程解析

    这篇文章主要介绍了Java使用split截取字符串过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 作用背景:一串字符串中的信息有些是有用的有些是多余的,我们需要把多余的信息去掉 例:"11,22,33,44,55" 这串字符串中我们要取出所有非","的内容 public class test { public static void main(String[] args) { String[] all =

  • php字符串截取中文截取2,单字节截取模式

    //中文截取2,单字节截取模式 function cn_substr($str,$slen,$startdd=0){     $restr = "";     $c = "";     $str_len = strlen($str);     if($str_len < $startdd+1) return "";     if($str_len < $startdd + $slen || $slen==0) $slen = $str

  • java中如何截取字符串最后一位

    目录 截取字符串最后一位 1.用substring()来截取 2.用split()来截取 3.对在Windows下的目录进行截取最后一位 4.对linux下的目录进行截取最后一位 截取字符串的常见方法 常用方法 常用方法介绍和应用示例 截取字符串最后一位 1.用substring()来截取 理论上它是按照字符串.substring(字符串.lastIndexOf("\\")+1)这个格式来的,但是在涉及到特殊符号时需要用\\来转义,所以注意下. 例子: public class Tes

  • JAVA 中实现整句汉字拆分、转换为ASCII实例详解

    JAVA 中实现整句汉字拆分.转换为ASCII实例详解 大家都知道,一个汉字等于两个byte的大小.二进制数据通过网络传输时,如果两个byte都超过128则会合并成一个Unicode(汉字)字符,本文的代码主要实现的功能是:把这些汉字拆分为byte,然后重新变为ASCII类型的字符串. public static String ChineseToASCII(byte[] rec) { //从字节读取内容 ByteArrayInputStream bais = new ByteArrayInput

随机推荐