字符串截取

对于字符串的剪取,比如:
在java中,字符串“abcd”与字符串“ab你好”的长度是一样,都是四个字符。
但对应的字节数不同,一个汉字占两个字节。
定义一个方法,按照指定的字节数来取子串。
如:对于“ab你好”,如果取三个字节,那么子串就是ab与“你”字的半个,那么半个就要舍弃。如果取四个字节就是“ab你”,取五个字节还是“ab你”。

在这里我需要注意的问题是,不同的编码格式对应的字节数也不同!在GBK中汉字是两个字节,而且大多都是两个负数,只有少部分的是一正一副的,所以我们需要考虑这个问题,
而在 UTF-8中所有的汉字都是3个负数,所以我们在写程序的时候应该注意这些问题

package io2;

import java.io.UnsupportedEncodingException;

public class StringCutDemo {

/**
 * 在java中,字符串“abcd”与字符串“ab你好”的长度是一样,都是四个字符。 但对应的字节数不同,一个汉字占两个字节。
 * 定义一个方法,按照指定的字节数来取子串。
 * 如:对于“ab你好”,如果取三个字节,那么子串就是ab与“你”字的半个,那么半个就要舍弃。如果取四个字节就是“ab你”,取五个字节还是“ab你”。
 */

public static void main(String[] args) {
    String str = "a你好fei緋";
    byte[] buf = null;
    // try {
    // // buf = str.getBytes("gbk");
    // buf = str.getBytes("utf-8");
    // } catch (UnsupportedEncodingException e) {
    // e.printStackTrace();
    // }
    buf = str.getBytes();
    System.out.println(str);
    // 观察
    for (byte b : buf) {
        System.out.print(b + " ");
    }
    System.out.println();
    // 测试
    System.out.println("---------------------");
    for (int i = 1; i <= buf.length; i++) {

        // String cutStr = cutByteStringGbk(str, i);// 用gbk格式截取
        // String cutStr = cutByteStringUtf(str, i);// 用utf-8格式截取
    //将俩种编码合并做成通用的
        String s = cutStringByByte(str, i);
        System.out.println("截取" + i + "个字节的结果是: " + s);
    }

}

private static String cutByteStringGbk(String str, int len) {
    try {
        // 重新用字节数组来装
        byte[] buff = str.getBytes("gbk");
        // 用for循环来判断,因为在GBK中汉字大多都是2个字节的负数,少部分是以正一负,我们可以从后往前截取
        int cout = 0;
        for (int i = len - 1; i >= 0; i--) {
            if (buff[i] > 0) {
                break;// 如果大于0说明到了字符,就可以停了
            }
            cout++;
        }
        // 用奇数和偶数来判断汉字
        if (cout % 2 == 0) {// 字节码值为负的字节的个数为偶数,则说明汉字刚好截整齐
            return new String(buff, 0, len, "gbk");
        } else {// 字节码值为负的字节的个数为奇数,则说明汉字多余1要舍去
            return new String(buff, 0, len - 1, "gbk");
        }
    } catch (UnsupportedEncodingException e) {
        return "";
    }
}

private static String cutByteStringUtf(String str, int len) {
    try {
        // 重新用字节数组来装
        byte[] buff = str.getBytes("utf-8");
        int cout = 0;
        for (int i = len - 1; i >= 0; i--) {
            if (buff[i] > 0) {
                break;// 如果大于0说明到了字符,就可以停了
            }
            cout++;
        }
        // 用奇数和偶数来判断汉字
        if (cout % 3 == 0) {// 字节码值为负的字节的个数为偶数,则说明汉字刚好截整齐
            return new String(buff, 0, len, "utf-8");
        } else {// 字节码值为负的字节的个数为奇数,则说明汉字多余1要舍去
            return new String(buff, 0, len - cout % 3, "utf-8");
        }
    } catch (UnsupportedEncodingException e) {
        return "";
    }
}

}

//合并类
private static String cutStringByByte(String str, int len) {
//System.getProperty(“file.encoding”)获取本地系统的编码格式

    if (System.getProperty("file.encoding").equalsIgnoreCase("gbk")) {          return cutByteStringGbk(str, len);
    }
    if (System.getProperty("file.encoding").equalsIgnoreCase("utf-8")) {
        return cutByteStringUtf(str, len);
    }
    return "";
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值