首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 字符串按字節截取且不截斷漢字

     編輯:Java 相關知識

需求

輸入字符串與字節數 len,按字節截取前 len 字節,**保證漢字不被截半**(UTF-8 下漢字 3 字節,GBK 下 2 字節)。

核心邏輯

  1. byte[] bytes = str.getBytes(charset) 獲取字節數組
  2. 若 len >= bytes.length 直接返回原串
  3. 檢查 bytes[len] (即第 len+1 個字節) 是否為 **負值**
  4. 若為負值,說明第 len 字節屬於多字節字符的**非首字節**(被截半),需 len-- 回退
  5. new String(bytes, 0, len, charset) 構造結果

完整代碼


public static String subByBytes(String src, int len, String charset) {
    if (src == null) return null;
    byte[] bytes = src.getBytes(Charset.forName(charset));
    if (len >= bytes.length) return src;
    // 回退直到字符邊界
    while (len > 0 && bytes[len] < 0) { // 負值表示非首字節
        len--;
    }
    return new String(bytes, 0, len, charset);
}

// 測試
public static void main(String[] args) {
    System.out.println(subByBytes("我ABC", 4, "GBK"));      // 我AB (漢字2字節)
    System.out.println(subByBytes("我ABC漢DEF", 6, "GBK")); // 我ABC (第6字節是漢字首字節,保留)
    System.out.println(subByBytes("我ABC", 4, "UTF-8"));    // 我A  (漢字3字節,第4字節屬於B)
}

關鍵點解析

  • 負值判斷:Java byte 有符號,多字節字符的**非首字節**最高位為 1 → 負值。首字節在 UTF-8/GBK 中也可能為負,但「被截半」時第 len 字節必為非首字節 → 負值
  • 循環回退:處理連續多字節字符被截斷的情況(如 UTF-8 3 字節漢字,len 落在中間需回退 2 步)
  • 編碼一致性:getBytes 與構造時**必須使用相同 Charset**,否則亂碼

JDK 內置替代方案

Java 9+ 可用 String.substring(int beginIndex, int endIndex) 配合 Character.isSupplementaryCodePoint,但仍需自行處理字節邊界。上述工具法通用性最強。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved