在截取指定长度字符时,我们可能会遇到单字节字符和双字节字符混和的情况(如中英文混合),我们如果用一个字符占一个长度的方法计算要截取的字符串长度,对不同字符串截取,得到的长度可能不一样
如: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. 如果isChWord为false, 把单个字符都看成一个长度。结果就是截取ostr的头len个字符返回
/// 如:CutLenStr("1234567", 2, false) 返回'12'
/// CutLenStr("一234567", 2, false) 返回'一2'
/// CutLenStr("一而似利古", 2, false) 返回'一而'
/// 2. 如果isChWord为true,把一个单字节字符都看成一个长度,把双字节字符(如中文字符,韩文,日文 )看成两个字符,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)//如果isChWord为false, 把所有单个字符都看成一个长度
{
return ostr.Length > len ? ostr.Substring(0, len) : ostr;
}
else //如果isChWord为true,把一个单字节字符都看成一个长度,把双字节字符(如中文字符,韩文,日文 )看成两个字符
{
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