利用二分法截取指定长度字符

 

在截取指定长度字符时,我们可能会遇到单字节字符和双字节字符混和的情况(如中英文混合),我们如果用一个字符占一个长度的方法计算要截取的字符串长度,对不同字符串截取,得到的长度可能不一样
如:CutLenStr("1234567", 2, false)         返回'12'
        CutLenStr("
一而似利古", 2, false)   返回'一而'
为解决这个问题,我们在计算字符串长度时就一该以字节长度为准。下面的方法就是以字节长度为准计算字符串长度的,采用的是二分法算法。

GetStrLen 获取字符串的字节长度#region GetStrLen 获取字符串的字节长度
        
/**//// <summary>
        
/// 获取字符串的字节长度
        
/// </summary>
        
/// <param name="s">字符串</param>
        
/// <returns>字符串的字节长度</returns>
        public static int GetStrLen(string s)
        
{
            
return System.Text.Encoding.Default.GetBytes(s).Length;    
        }
        
#endregion

 

CutLenStr 截取指定长度字符 (二分法)#region CutLenStr 截取指定长度字符 (二分法)
        
/**//// <summary>
        
/// 截取指定长度字符
        
/// 1. 如果isChWordfalse, 把单个字符都看成一个长度。结果就是截取ostr的头len个字符返回
        
/// 如:CutLenStr("1234567", 2, false) 返回'12'
        
///     CutLenStr("234567", 2, false) 返回'2'
        
///     CutLenStr("一而似利古", 2, false) 返回'一而'
        
/// 2. 如果isChWordtrue,把一个单字节字符都看成一个长度,把双字节字符(如中文字符,韩文,日文 )看成两个字符,len表示的是双字节个数。
        
/// 如:CutLenStr("1234567", 2, true) 返回'1234'
        
///     CutLenStr("234567", 2, false) 返回'23'
        
///     CutLenStr("一而似利古", 2, false) 返回'一而'
        
/// </summary>
        
/// <param name="ostr">原字符串</param>
        
/// <param name="len">截取长度</param>
        
/// <param name="isChWord">是否中文长度为准</param>
        
/// <returns>
        
/// 截取的指定长度字符
        
/// </returns>
        
/// <remarks>
        
/// 在截取指定长度字符时,我们可能会遇到单字节字符和双字节字符混和的情况(如中英文混合),
        
/// 我们如果用一个字符占一个长度的方法计算要截取的字符串长度,对不同字符串截取,得到的长度可能不一样
        
/// 如:CutLenStr("1234567", 2, false)    返回'12'
        
///     CutLenStr("一而似利古", 2, false) 返回'一而'
        
/// 为解决这个问题,我们在计算字符串长度时就一该以字节长度为准。下面的方法就是以字节长度为准计算字符串长度的,采用的是二分法算法。
        
/// </remarks>
        public static string CutLenStr(string ostr, int len, bool isChWord)
        
{
            
if (isChWord == false)//
如果isChWordfalse, 把所有单个字符都看成一个长度
             {
                
return ostr.Length > len ? ostr.Substring(0, len) : ostr;
            }
            
else //如果isChWordtrue,把一个单字节字符都看成一个长度,把双字节字符(如中文字符,韩文,日文 )看成两个字符
             {
                
if (ostr.Length == 1 && len > 0)
                    
return ostr;
                
if (len == 1 && ostr.Length > 0)
                    
return ostr.Substring(0, 1);
                
int lenc = len * 2;
                
int ostrLen = GetStrLen(ostr);
                
if (ostrLen <= lenc)
                    
return ostr;

                
return GetLenStr(ostr, ref ostr, lenc);

            }
        }

        
private static string GetLenStr(string str, ref string ostr, int len)
        
{
            
int totalLen = GetStrLen(str);
            
if (totalLen == len)
                
return str;

            
if (totalLen + 1 == len)
            
{
                
string astr = ostr.Substring(0, str.Length + 1);
                
if (GetStrLen(astr) == len)
                
{
                    
return astr;
                }
                
return str;
            }


            
if (totalLen - 1 == len)
            
{
                
string dstr = ostr.Substring(0, str.Length - 1);
                
if (GetStrLen(dstr) <= len)
                
{
                    
return dstr;
                }
                
return str;
            }

            
if (totalLen < len)
            
{
                
int temp = str.Length + Convert.ToInt32((len - totalLen) * 0.5);
                str = ostr.Substring(0, temp);
                
return GetLenStr(str, ref ostr, len);
            }
            
else
            
{
                
int temp = Convert.ToInt32((totalLen - len) * 0.5);
                str = ostr.Substring(0, temp);
                
return GetLenStr(str, ref ostr, len);
            }
        }

        
#endregion

 

posted on 2006-12-22 23:14  刘新春  阅读(247)  评论(0)    收藏  举报

导航