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

Java按字節截取字符串並保證中文字符不拆分實現

     編輯:Java 相關知識

需求:按指定字節長度截取字符串,中文字符佔 2 字節,英文佔 1 字節,**不能將中文字符截半**。本文提供基於正則識別中文、字節計數器的完整實現,並分析邊界情況與性能優化。

一、核心邏輯

  1. 遍歷字符串每個字符
  2. 正則 [\\u4e00-\\u9fa5] 判斷是否中文
  3. 中文 +2,非中文 +1 累加字節計數
  4. 計數達到限制輸出當前片段,歸零繼續
  5. 超過限制時:當前字符不輸出,換行後重新計數

二、完整實現代碼

import java.util.Scanner;

public class ByteSubstring {
    private static final String CHINESE_REGEX = "[\\u4e00-\\u9fa5]";

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("請輸入字符串:");
        String input = sc.nextLine();
        System.out.print("請輸入字節數:");
        int byteLimit = sc.nextInt();

        System.out.println("按 " + byteLimit + " 字節分段結果:");
        splitByByte(input, byteLimit);
    }

    public static void splitByByte(String str, int limit) {
        if (str == null || limit <= 0) return;

        int count = 0;
        StringBuilder segment = new StringBuilder();

        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            String chStr = String.valueOf(ch);
            int byteLen = chStr.matches(CHINESE_REGEX) ? 2 : 1;

            if (count + byteLen < limit) {
                segment.append(ch);
                count += byteLen;
            } else if (count + byteLen == limit) {
                segment.append(ch);
                System.out.println(segment);
                segment.setLength(0);
                count = 0;
            } else { // 超過限制
                if (segment.length() > 0) System.out.println(segment);
                segment.setLength(0);
                segment.append(ch);
                count = byteLen;
            }
        }
        if (segment.length() > 0) System.out.println(segment);
    }
}

三、測試用例與輸出

輸入字符串字節限制輸出段落說明
我ABC4我AB
C
「我」(2) + A(1) + B(1) = 4 滿足
我ABC漢DEF6我ABC
漢DE
F
第2段「漢」(2)+D(1)+E(1)=4 未滿6,但下一字符 F 會超,故換行
Hello世界5Hello
世
界
純英文 5 字節恰好;中文各佔 2 字節單獨成段
😀Emoji4😀E
moji
Emoji 為增補字符,Java char 視為 2 個代碼單元(4字節),邏輯視為 2 字符

四、增補字符 (Emoji/生僻字) 處理補充

上述代碼基於 char 遍歷,**無法正確處理增補字符**(佔 2 個 char,即 4 字節 UTF-16)。Java 8+ 正確做法:

public static void splitByByteCorrect(String str, int limit) {
    int count = 0;
    StringBuilder seg = new StringBuilder();
    int cp;
    for (int i = 0; i < str.length(); i += Character.charCount(cp)) {
        cp = str.codePointAt(i);
        String chStr = new String(Character.toChars(cp));
        // 簡單估算:BMP 字符按編碼判斷,增補字符統計為 4 字節 (UTF-8 通常 4 字節)
        int byteLen = (cp <= 0xFFFF) ? (chStr.matches(CHINESE_REGEX) ? 2 : 1) : 4;

        if (count + byteLen <= limit) {
            seg.append(chStr);
            count += byteLen;
        } else {
            if (seg.length() > 0) System.out.println(seg);
            seg.setLength(0);
            seg.append(chStr);
            count = byteLen;
        }
    }
    if (seg.length() > 0) System.out.println(seg);
}

五、性能優化建議

  1. 預編譯正則:Pattern CHINESE_PATTERN = Pattern.compile(CHINESE_REGEX)
  2. 避免 String.matches() 隱式編譯,改用 matcher(chStr).matches()
  3. 大字符串分段輸出時,使用 StringBuilder 批量寫入 PrintWriter
  4. 若僅需截取前 N 字節,可直接 byte[] bytes = str.getBytes(StandardCharsets.UTF_8) 截取後解碼,但需處理半個字符殘留

六、總結

按字節截取字符串核心在於**字符級遍歷 + 字節長度累加 + 邊界判斷**。生產代碼建議封裝為工具類,支持指定編碼(UTF-8/GBK)、增補字符正確處理、流式處理大文本。

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