思考:解決問題之前,我們需要了解的是,在GB2312字符集的編碼中漢字佔2個字節,字母和其他字符佔一個字節,而在utf-8中漢字佔3,或者4個字節,字母佔2個字節,由於utf一下佔2個3個字節,一下佔4個字節,不好拆分出指定的漢字加字母,所以才用GB2312的編碼格式,漢字佔2個字節,字母一個字節。
GB2312規定對收錄的每個字符采用兩個字節表示,第一個字節爲“高字節”,對應94個區;第二個字節爲“低字節”,對應94個位。所以它的區位碼範圍是:0101-9494。區號和位號分別加上0xA0就是GB2312編碼。例如最後一個碼位是9494,區號和位號分別轉換成十六進制是5E5E,0x5E+0xA0=0xFE,所以該碼位的GB2312編碼是FEFE。
GB2312編碼範圍:A1A1-FEFE,其中漢字的編碼範圍爲B0A1-F7FE,第一字節0xB0-0xF7(對應區號:16-87),第二個字節0xA1-0xFE(對應位號:01-94)。A-F的二進制最高位都爲1
所以:在把漢字轉換成字節的時候,輸出的字節的值小於0,字母轉換成字節的時候,輸出的值就是其對應的數字。
編寫一個截取字符串的函數,輸入爲一個字符串和字節數,輸出爲按字節截取的字符串。 但是要保證漢字不被截半個。
如“我ABC”4,應該截爲“我AB”,輸入“我ABC漢DEF”,6,應該輸出爲“我ABC”而不是“我ABC+漢的半個”。
public static String splitString(String str, int byteLength)
throws Exception {
//如果字符串爲空,直接返回
if(str == null || "".equals(str)) {
return str;
}
//用於統計這個字符串中有幾個中文字符
int wordCount = 0;
//統一按照gbk編碼來得到他的字節數組,因爲不同的編碼字節數組是不一樣的。
byte[] strBytes = str.getBytes("GB2312");
//如果只截取一位,而且第一位是中文字符時的處理
if (byteLength == 1) {
if (strBytes[0] < 0) {
return str.substring(0, 1);
}
}
//字符串中的一箇中文會使得wordCount 加兩次
//如果你這個字節取出來的是一個漢字也就是兩個字節當中的一個的話val的值爲負數
for (int i = 0; i < byteLength; i++) {
int val = strBytes[i];
if (val < 0) {
wordCount++;
}
}
//如果傳遞的這個截取的位數沒有截到半個中文上面,那麼就按照byteLength - (wordCount / 2)個長度進行截取
if (wordCount % 2 == 0) {
return str.substring(0, (byteLength - (wordCount / 2)));
}
//否則,我們就捨棄多出來的這一位 所以 -1
return str.substring(0, (byteLength - (wordCount / 2) - 1));
}
第二種方式是用正則表達式、Unicode 編碼來判斷
https://blog.csdn.net/yspxiaopanni/article/details/93624871
Java用的是Unicode 編碼char 型變量的範圍是0-65535 無符號的值,可以表示 65536個字符。
unicode編碼範圍:
漢字:[0x4e00,0x9fa5](或十進制[19968,40869])
數字:[0x30,0x39](或十進制[48, 57])
小寫字母:[0x61,0x7a](或十進制[97, 122])
大寫字母:[0x41,0x5a](或十進制[65, 90])
漢字編碼範圍:\u4e00-\u9FA5
雙字節字符編碼範圍:\u0391-\uFFE5
第一步:判斷是否存在漢字
public boolean generateJudgment(String countname)
{
Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
Matcher isNum = p.matcher(countname);
if (isNum.find()) {
return true;
}
return false;
}
JAVA正則表達式:Pattern類與Matcher類
待補充
getBytes()方法詳解
https://blog.csdn.net/ljheee/article/details/51476125
在Java中,String的getBytes()方法是得到一個操作系統默認的編碼格式的字節數組。這表示在不同的操作系統下,返回的東西不一樣!
1、 str.getBytes(); 如果括號中不寫charset,則採用的是Sytem.getProperty("file.encoding"),即當前文件的編碼方式,
2、 str.getBytes("charset");//指定charset,即將底層存儲的Unicode碼解析爲charset編碼格式的字節數組方式
3、String str=new String(str.getBytes("utf-8"),"gbk")); //
將已經解析出來的字節數據轉化爲gbk編碼格式的字符串,在內存中即爲gbk格式的字節數組轉爲Unicode去交互傳遞