在網頁或報表顯示標題、摘要時,常需限制字串顯示寬度。中文字佔兩個英文字元寬度,單純用 Substring 會導致版面錯位。本文提供一個靜態方法,依「中文算 2、英文算 1」的規則截取字串,超過長度自動加上 .. 省略號。
using System;
using System.Text;
using System.Text.RegularExpressions;
public static class StringHelper
{
///
/// 依顯示寬度截取字串(中文=2,英文/數字/符號=1),超過長度加上省略號
///
/// 原始字串
/// 最大顯示寬度
/// 截取後字串
public static string SubstringByWidth(string input, int maxWidth)
{
if (string.IsNullOrEmpty(input) || maxWidth <= 0)
return string.Empty;
// 預編譯正則:判斷是否為中文字元 (CJK Unified Ideographs)
static readonly Regex ChineseRegex = new Regex("[\u4e00-\u9fa5]", RegexOptions.Compiled);
char[] chars = input.ToCharArray();
StringBuilder sb = new StringBuilder();
int currentWidth = 0;
bool isCut = false;
for (int i = 0; i < chars.Length; i++)
{
char c = chars[i];
int charWidth = ChineseRegex.IsMatch(c.ToString()) ? 2 : 1;
if (currentWidth + charWidth > maxWidth)
{
isCut = true;
break;
}
sb.Append(c);
currentWidth += charWidth;
}
return isCut ? sb.ToString() + ".." : sb.ToString();
}
}
string title1 = "最新C#程式設計教學";
string title2 = "Latest C# Programming Tutorial";
string title3 = "C# 程式設計入門 Guide";
Console.WriteLine(StringHelper.SubstringByWidth(title1, 10)); // 最新C#程..
Console.WriteLine(StringHelper.SubstringByWidth(title2, 20)); // Latest C# Prog..
Console.WriteLine(StringHelper.SubstringByWidth(title3, 15)); // C# 程式設計..
[\u4e00-\u9fa5] 涵蓋基本中日韓統一表意文字區塊。若需支援擴展區 (如生僻字),可改用 \p{IsCJKUnifiedIdeographs}。currentWidth + charWidth > maxWidth,若超過即中斷,避免半個中文被切斷。RegexOptions.Compiled 提升重複呼叫效能,避免每次重新編譯模式。[\u4e00-\u9fa5\uFF00-\uFFEF] 涵蓋全形標點、數字。string ellipsis = ".." 讓呼叫端決定。FormattedText 或 TextRenderer.MeasureText 依實際字型像素寬度截取,更精確。此方法解決中英混排固定寬度顯示的經典問題,程式碼簡潔、效能良好,適合 Web (Razor/Blazor)、桌面應用、報表產生器等場景。實際專案中建議封裝為擴充方法 public static string SubstringByWidth(this string s, int width) 方便呼叫。