java中通过字节对字符串进行截取,本文的背景是中英文混合在一起,gbk,utf-8等编码的中英文字节数不对应,导致难以截取。
这里使用Unicode编码的方式进行转换,在Unicode中每个字符均使用两个字节来记录,其中数字及英文字母第一个字节必是0 ,且第一个,第二个为标记码,需要跳过。
核心思想:现将字符串转为字节数组,然后遍历数组,只要遇到偶数角标字节数就加一,奇数角标则进一步判断前一个角标对应的内容是否为0,如果不为0,则为中文,中文占两个字节,因此此处的字节数也要加1,反之前一位为0,则不加1;如果用于指定的起始字节正好是中文的第二个字节,会导致乱码,需要用户重新输入,结尾乱码不做处理。
代码如下;
package p1;
import java.io.UnsupportedEncodingException;
import java.util.Scanner;
public class Test03 {
public static void main(String[] args) throws Exception {
subStrByBytes();
}
public static int subStrByBytes() throws Exception {
int check=0;
Scanner sc = new Scanner(System.in);
Scanner sc2 = new Scanner(System.in);
Scanner sc3 = new Scanner(System.in);
System.out.println("请输入您想截取的文本");
String useWord = sc.nextLine();
byte[] bytes =useWord.getBytes("Unicode");
System.out.println("请输入开始截取的字节数");
int start = sc2.nextInt();
System.out.println("请输入结束截取的字节数");
int end = sc3.nextInt();
int len =end-start+1;
if ((end-start)>bytes.length) {
System.out.println("您输入的截取长度超过原文本,已经为您返回原文本,如下");
System.out.println(useWord);
return 666;
}
int n = 0,n1=0,n3=0,n4=0;
for (int i = 2; i < bytes.length; i++) {
if (i%2==0) {
n++;
}else {
if (bytes[i-1]!=0) {
n++;
}
}
if (n==start) {
if (i%2!=0) {
System.out.println("起始位置为中文后半截,请重新制定以免乱码");
check = subStrByBytes();
start=i-1;
break;
}else {
start=i;
break;
}
}
}
if (check==666) {
return 404;
}
for (int i = start; i < bytes.length; i++) {
if (i%2==0) {
n1++;
}else {
if (bytes[i-1]!=0) {
n1++;
}
}
if (n1==len) {
if (i%2==0) {
if (bytes[i]==0) {
end=i-start+2;
break;
}
}else {
end = i-start+1;
break;
}
}
}
String string = new String(bytes,start,end,"unicode");
System.out.println("截取后的文本为:"+string);
return 666;
}
}