原帖由 Brandon 于 2008-3-13 11:11:00 发表
今天花了点时间研究了一下2.0代码里的Discuz.Common.Utils.GetSubString(string p_SrcString, int p_StartIndex, int p_Length, string p_TailString)函数
这段代码在英文系统下是存在问题的。
首先对于以下这两段测试字符串:
1. 加拿大安大略Algonquin Park游记
2. 用一个位
做了一点点修改:
//////////////////////////////////////////////////////////////////////////
///
///
/// 加拿大安大略Algonquin Park游记
/// 用一个位元组表示,超出ASCII码的范围就用位元组表示
/// 当要截取的长度在字符串的有效长度范围内
/// αβγδεζηθικλμνξοπρΣτυφχψω
/// 後に生まれたものでもある。今日でも現代ギリシア語の表記に用いられ
/// 장나라 아시아통합음반의 의의
///
///
/// <summary>
/// 取指定长度的字符串
/// </summary>
/// <param name="p_SrcString">要检查的字符串</param>
/// <param name="p_StartIndex">起始位置</param>
/// <param name="p_Length">指定长度</param>
/// <param name="p_TailString">用于替换的字符串</param>
/// <param name="p_MultiByte">一个非英文字符是否按多字节计算,不包括重音文字、希腊字母或西里尔字母</param>
/// <returns></returns>
public static string GetSubString(string p_SrcString, int p_StartIndex, int p_Length, string p_TailString, bool p_MultiByte)
{
string myResult = "";
int nUTF8Length = 0;
int nUTF8StartIndex = 0;
int iSrcLength = 0;
int iSrcStartIndex = 0;
bool bHasUTF8StartIndex = false;
bool bHasUTF8Length = false;
if (p_StartIndex % 2 > 0)
p_StartIndex--;
if (p_Length % 2 > 0)
p_Length--;
byte[] bsSrcString = Encoding.UTF8.GetBytes(p_SrcString);
for (int iUTF8 = 0; iUTF8 < bsSrcString.Length; iUTF8++)
{
if (iSrcStartIndex >= p_StartIndex && !bHasUTF8StartIndex)
{
bHasUTF8StartIndex = true;
nUTF8StartIndex = iUTF8;
}
if (iSrcLength - p_StartIndex >= p_Length && !bHasUTF8Length)
{
bHasUTF8Length = true;
nUTF8Length = iUTF8 - nUTF8StartIndex;
}
if (bHasUTF8Length && bHasUTF8StartIndex)
break;
int extendLength = 0;
if (bsSrcString[iUTF8] >= 0xFD) //1111110x
extendLength = 5;
else if (bsSrcString[iUTF8] >= 0xF9) //111110xx
extendLength = 4;
else if (bsSrcString[iUTF8] >= 0xF1) //11110xxx
extendLength = 3;
else if (bsSrcString[iUTF8] >= 0xE1) //1110xxxx
extendLength = 2;
else if (bsSrcString[iUTF8] >= 0xC1) //110xxxxx
extendLength = 1;
else //0xxxxxxx
extendLength = 0;
if (p_MultiByte && bsSrcString[iUTF8] >= 0xE1)
{
iSrcLength += extendLength;
iSrcStartIndex += extendLength;
}
else
{
iSrcLength++;
iSrcStartIndex++;
}
iUTF8 += extendLength;
}
if (!bHasUTF8Length)
{
nUTF8Length = bsSrcString.Length - nUTF8StartIndex;
p_TailString = "";
}
byte[] bsResult = new byte[nUTF8Length];
Array.Copy(bsSrcString, nUTF8StartIndex, bsResult, 0, nUTF8Length);
myResult = Encoding.UTF8.GetString(bsResult);
myResult = myResult + p_TailString;
return myResult;
}