在處理定長字串截取、資料庫欄位長度驗證或傳統系統介接時,常需依據「中文字佔 2 個字元、英數字佔 1 個字元」的規則計算字串長度。.NET Framework 內建的 String.Length 屬性僅回傳 Char 數量(UTF-16 代碼單元),無法直接滿足此需求。本文提供兩個實用的擴充方法,精確實現雙字節長度計算與定長截取。
判斷依據:Unicode 編碼中,基本多文種平面(BMP)的中日韓統一表意文字碼點通常大於 255(0xFF)。因此,透過 Convert.ToInt32(char) > 255 即可簡易區分:
private int GetLength(string orgStr)
{
int len = orgStr.Length; // 基礎長度(每字元算 1)
foreach (char c in orgStr)
{
if (Convert.ToInt32(c) > 255) len++; // 雙字節字元額外加 1
}
return len;
}
原理:先以字元數為基準,遇到雙字節字元則再加 1,最終等同於「單字節×1 + 雙字節×2」。
private string MutiSubString(string orgStr, int length, ref string afterStr)
{
int start = 0, end = orgStr.Length, singleCount = 0;
char[] chars = orgStr.ToCharArray();
for (int i = 0; i < chars.Length; i++)
{
if (Convert.ToInt32(chars[i]) > 255) start += 2;
else { start += 1; singleCount++; }
if (start >= length)
{
// 處理邊界:確保不截斷雙字節字元
if (length % 2 == 0)
end = (singleCount % 2 == 0) ? i + 1 : i;
else
end = i + 1;
break;
}
}
string result = orgStr.Substring(0, end);
afterStr = orgStr.Remove(0, end);
return result;
}
關鍵點:
start 模擬雙字節長度singleCount 協助邊界判斷ref 參數回傳剩餘字串,方便連續處理string afterStr;
string result = MutiSubString("abc漢字字符", 5, ref afterStr);
// result = "abc漢" (a=1,b=1,c=1,漢=2 → 總長 5)
// afterStr = "字字符"
此實作有效解決了 String.Length 將中文視為單字元的問題,適用於定長檔案產生、舊系統資料遷移、報表列印對齊等場景。若需支援補充平面字符(Emoji、罕用字),建議改用 StringInfo 類或 Rune 結構(.NET Core 3.0+)處理代碼點。