对于字符串的剪取,比如:
在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 "";
}