C# 按字节数截取字符串并添加省略号的实现

小鹿同学
小鹿同学
发布时间:2026-10-14 | 5人浏览过
原创

C# 内置的字符串截取主要基于字符数量而非字节数,但在处理数据库存储、日志打印或 API 传输等受字节长度限制的场景时,需要精确控制。由于不同字符(如中文与英文)在不同编码下占用的字节不同,直接按字符数截取易导致末尾字符被截断一半而引发乱码。本文将演示如何通过遍历字符并累加字节长度,安全地将字符串截断到指定字节并在末端补充 "..."。

按字节数截取并追加省略号的方法

该函数的核心逻辑是依次读取字符串中的每个字符,将其转换为指定的字节编码并累加计数。一旦累计字节数达到或超过目标值,立即停止循环并返回子串。这种方法能有效避免将双字节或三字节字符截断为非法字节序列。

第1步:定义包含省略号的截取函数

首先引入必要的命名空间(若未全局引入),并创建静态辅助方法 GetSubString。以下是完整的 C# 实现代码:

public static string GetSubString(string origStr, int endIndex)
{
    // 1. 边界检查:输入为空或截取长度为负数时,直接返回空字符串
    if (origStr == null || origStr.Length == 0 || endIndex < 0)
        return "";

    // 此处使用 gb2312 编码计算总字节数(可根据实际需求切换为 Encoding.UTF8)
    int bytesCount = System.Text.Encoding.GetEncoding("gb2312").GetByteCount(origStr);

    // 如果总字节数不超过限制,直接返回原字符串
    if (bytesCount <= endIndex)
        return origStr;

    int readyLength = 0;
    int byteLength;

    // 2. 逐字符累加字节数
    for (int i = 0; i < origStr.Length; i++)
    {
        // 获取单个字符在当前编码下的字节长度
        byteLength = System.Text.Encoding.GetEncoding("gb2312").GetByteCount(new char[] { origStr[i] });
        readyLength += byteLength;

        // 3. 当刚好等于目标长度时,截取包含当前字符的部分并加上省略号
        if (readyLength == endIndex)
        {
            origStr = origStr.Substring(0, i + 1) + "...";
            break;
        }
        // 4. 当超过目标长度时,不截取当前字符,保持之前的截断位置,并加上省略号
        else if (readyLength > endIndex)
        {
            origStr = origStr.Substring(0, i) + "...";
            break;
        }
    }
    return origStr;
}

第2步:理解参数与执行结果

  • 参数说明:
    • origStr:需要进行截断处理的原始字符串。
    • endIndex:截取的目标字节总数(例如:10代表最多占用10个字节)。
  • 注意事项:
    • 原代码中使用了 Encoding.GetEncoding("gb2312")。如果您的系统环境默认为 UTF-8(如在 Linux 服务器或现代 Web 开发中),请替换为 Encoding.UTF8,否则可能导致中文显示为乱码或占用字节计算偏差。
    • 算法通过逐个字符增加长度,确保了不会切断一个汉字的中间部分。比如遇到一个 2 字节的汉字,若前 1 个字节已达上限,则该字符会被整体舍弃。

无后缀的精确字节截取方案

在某些 UI 界面设计或数据对齐场景中,可能只需要纯粹的截断而不希望出现末尾的标点符号。逻辑与上述方法一致,唯一的区别是移除字符串拼接操作。

// 按字节数截取字符串(不带省略号)
public static string GetSub1String(string origStr, int endIndex)
{
    if (origStr == null || origStr.Length == 0 || endIndex < 0)
        return "";

    int bytesCount = System.Text.Encoding.GetEncoding("gb2312").GetByteCount(origStr);
    if (bytesCount > endIndex)
    {
        int readyLength = 0;
        int byteLength;
        for (int i = 0; i < origStr.Length; i++)
        {
            byteLength = System.Text.Encoding.GetEncoding("gb2312").GetByteCount(new char[] { origStr[i] });
            readyLength += byteLength;
            
            // 相等或大于时的截取逻辑略去了省略号拼接
            if (readyLength == endIndex)
            {
                origStr = origStr.Substring(0, i + 1);
                break;
            }
            else if (readyLength > endIndex)
            {
                origStr = origStr.Substring(0, i);
                break;
            }
        }
    }
    return origStr;
}

性能优化建议

上述 `for` 循环方式虽然直观且准确,但如果字符串极长或调用频率极高,频繁实例化数组 new char[] { ... } 可能会产生一定开销。在实际生产环境中,如果确认使用的是固定宽度编码或者为了追求极致性能,也可以结合正则表达式或更底层的 `System.Text.Encoding` 缓冲区处理方法进行优化,但对于常规业务逻辑,当前的逐字累加法足以保证安全性与可读性。

以上就是 C# 根据字节数截取字符串并加上省略号的详细内容,更多关于 C# 字符串处理的技术资料请关注本站其它相关文章!
相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表