Hi, BeNuts!

BeNuts 程序官方博客

 

在C#中截取指定长度的中文字符串(效率提高2500倍)

作者: uonun 发表时间: 2009-7-8 18:03:00
永久链接: http://udnz.com/Article/CutStr.aspx

C#中字符串截断本没有那么麻烦,问题就出在string.Substring()这个方法将中文也按一个字符计算,导致我们在实际应用中截取字符串(中英文组合)后的“长度”不一致。

国际惯例,在网上搜索了一下,大致得到了两中截断算法:
1. 从起始位置取得字符 -> 逐一用正则表达式匹配 -> 拼接成最终字符串。(这是广为流传的方法,也是效率最低的方法。)
2. 从起始位置取得字符 -> 逐一用ASCII比较 -> 再拼接成最终字符串。

相比之下,算法2比算法1高明,毕竟ASCII比较比正则表达式的执行效率更高。但最终,我仍然没有使用算法2,而是进行了进一步的优化:

public static string CutStr(string str, int len)
{
    if (str == null || str.Length == 0 || len <= 0)
    {
        return string.Empty;
    }

    int l = str.Length;

    #region 计算长度
    int clen = 0;
    while (clen < len && clen < l)
    {
        //每遇到一个中文,则将目标长度减一。
        if ((int)str[clen] > 128) { len--; }
        clen++;
    }
    #endregion

    if (clen < l)
    {
        return str.Substring(0, clen) + "...";
    }
    else
    {
        return str;
    }
}

最后,通过比较,广为流传的算法1执行100次就需要700多毫秒,而我的算法700毫秒可执行250000次!
(注:实际运行时间和原始字符串长度、截取长度、电脑性能有关。但同条件下的效率比值是基本稳定的。)

2 Comments for this post.

 
 游客 Says:

这是你的算法?你查查javascript版本的,早就有了

管理员 uonun 的回复:

哦,抱歉。虽然我不是第一个这么用的人,但这么用我是自己想出来的,也算原创了。如果不算的话,那么……好吧,“我用的”,不是“我的”,呵呵。

PS: 我觉得非洲第一个吃螃蟹的人和亚洲第一个吃螃蟹的人都是第一个——例子不恰当,哈哈。

 
 
 游客 Says:

这个方法好!

 

  • * 姓名(Name)
  • E-mail 或网站网址。支持基于 E-mail 的 Gravatar 头像。
  • * 验证码 看不清?点击换一个!