在 Java 開發中,字符串截取是常見需求,但單純使用 substring 往往會導致中英文混排時長度計算不準確,因為中文字符佔兩個字節,英文佔一個。本文整理了多種精確截取方案,幫助你根據業務場景選擇最合適的實現。
直接按字符數截取(如 str.substring(0, 100))會忽略中英文字節差異,導致顯示長度不一致。正確做法是按字節長度截取,並補全省略符號。
public String getLimitLengthString(String str, int len, String symbol) throws UnsupportedEncodingException {
byte[] bytes = str.getBytes("GBK");
if (bytes.length <= len) return str;
int doubleByteCount = 0;
for (int i = 0; i < len; i++) {
if (bytes[i] < 0) doubleByteCount++;
}
// 避免截斷雙字節字符
int end = (doubleByteCount % 2 == 0) ? len : len - 1;
return new String(bytes, 0, end, "GBK") + symbol;
}
此法利用 GBK 編碼特性,統計負字節(高位字節)判斷雙字節字符,確保不截半個漢字。
public static String substring(String str, int byteLen, String suffix) {
if (str == null) return "";
char[] chars = str.toCharArray();
int count = 0;
StringBuilder sb = new StringBuilder();
for (char c : chars) {
int charBytes = String.valueOf(c).getBytes().length; // 默認編碼
if (count + charBytes > byteLen) break;
sb.append(c);
count += charBytes;
}
if (count < byteLen) sb.append(suffix);
return sb.toString();
}
逐字符計算字節長度,適用於 UTF-8 等多字節編碼環境,靈活性更高。
function getInterceptedStr(str, len) {
const regex = /[^\x00-\xff]/g;
if (str.replace(regex, "xx").length <= len) return str;
let result = "", byteCount = 0;
for (let i = 0; i < str.length; i++) {
const ch = str.charAt(i);
result += ch;
byteCount += regex.test(ch) ? 2 : 1;
if (byteCount >= len) break;
}
return result + "...";
}
前端同樣需處理雙字節字符,正則匹配非 ASCII 字符作為雙字節計算。
text-overflow: ellipsis 實現純前端截斷,減少後端壓力。掌握這些技巧,能有效解決列表頁、摘要顯示等場景的字符串截取難題,提升用戶體驗與數據完整性。