您的位置:首页 > 产品设计 > UI/UE

类似于StringBuilder的字符串加强处理类

2016-05-20 10:55 429 查看
大家都知道StringBuilder的用途,但是StringBuilder提供的功能却实在是太少了.特别是在处理字符串不区分大写时它就不能为力了.只能够将它里面的数据提取出来进行处理然后再放回进去,但这样做的话这里转来转去耗费资源就太多了

这是我们不想要的结果。而刚好我在做一个模版对象时就需要这种能够快速处理字符串的需求,所以StringBuilder就不再符合要求只能自己做一个仿照于它并加强部分功能的TextBuilder……

我们都知道StringBuilder是在内部维护一个字符数组的,所以我们也是从字符数组里下手用于做我们的string缓冲,而在C#里能够快速操作字符数组的也许就需要使用微软不推荐使用的“指针”了(呵呵,别头痛,虽然我也对指针很头痛,但这里用的指针很简单,你可以看成是一个数组的int索引编号值)

因我的文字表达能力很差,所以我直接提供代码,希望各位能够看懂


注:以下代码并非真正个人原创,我只是在原作者的基础上修改并加强部分功能(有中文注解的则是本人所加功能



如果编译以下代码必须将unsafe打开,否则不能编译


using System;


using System.IO;


using System.ComponentModel;


using System.Runtime.InteropServices;


namespace Kingthy.Library.Text


{


/// <summary>


/// TextBuilder : 类似于StringBuilder的字符串处理类


/// </summary>


public sealed class TextBuilder


{


#region 构造函数


public TextBuilder()


{


}


public TextBuilder(int initialCapacity)


{


if (initialCapacity < PaddingSize)


{


initialCapacity = PaddingSize;


}


this.EnsureCapacityInternal(initialCapacity);


}


public TextBuilder(string s) : this(s.ToCharArray(), 0, s.Length)


{


}


public TextBuilder(char[] chars) : this(chars, 0, chars.Length)


{


}


public TextBuilder(char[] chars, int startIndex, int length)


{


if (length != 0)


{


this.EnsureCapacityInternal(length);


TextBuilder.UnsafeCopyChars(this._data, 0, chars, startIndex, length);


this._length = length;


}


}


#endregion




#region 从文件载入数据


/// <summary>


/// 从文本文件载入


/// </summary>


/// <param name="fileName"></param>


/// <returns></returns>


public static TextBuilder FromFile(string fileName)


{


return TextBuilder.FromFile(fileName,System.Text.Encoding.Default);


}


/// <summary>


/// 从文本文件载入


/// </summary>


/// <param name="fileName"></param>


/// <param name="charset"></param>


/// <returns></returns>


public static TextBuilder FromFile(string fileName,System.Text.Encoding charset)


{


TextBuilder text = null;


StreamReader stream = null;


try


{


stream = new StreamReader(fileName,charset);




text = new TextBuilder(stream.ReadToEnd());


}


catch


{


text = null;


}


finally


{


if(stream != null)stream.Close();


}


return text;


}


#endregion




#region 添加字符


public TextBuilder Append(string s)


{


return this.Append(s.ToCharArray(), 0, s.Length);


}


public TextBuilder Append(char[] chars)


{


return this.Append(chars, 0, chars.Length);


}




public TextBuilder Append(char ch)


{


this.EnsureCapacityInternal(this._length + 1);


this._data[this._length++] = ch;


this.MakeDirty();


return this;


}






public TextBuilder Append(char[] chars, int length)


{


return this.Append(chars, 0, length);


}




public TextBuilder Append(string s, int length)


{


return this.Append(s.ToCharArray(0, length), 0, length);


}


public TextBuilder Append(string s, int startIndex, int length)


{


return this.Append(s.ToCharArray(startIndex, length), 0, length);


}




public TextBuilder Append(char[] chars, int startIndex, int length)


{


if(length < 1)return this;


if (chars == null)


{


throw new ArgumentNullException("chars");


}


if ((startIndex < 0) || (chars.Length < (startIndex + length)))


{


throw new ArgumentOutOfRangeException();


}


this.EnsureCapacityInternal(this._length + length);


TextBuilder.UnsafeCopyChars(this._data, this._length, chars, startIndex, length);


this._length += length;


this.MakeDirty();


return this;


}










//添加字符并添加新的一行


public TextBuilder AppendLine(string s)


{


return this.AppendLine(s.ToCharArray(), 0, s.Length);


}


public TextBuilder AppendLine(char[] chars)


{


return this.AppendLine(chars, 0, chars.Length);


}




public TextBuilder AppendLine(char ch)


{


string newLine = string.Concat(ch,System.Environment.NewLine);


this.EnsureCapacityInternal(this._length + newLine.Length);


for(int i=0; i<newLine.Length; i++)


{


this._data[this._length++] = newLine[i];


}


this.MakeDirty();


return this;


}






public TextBuilder AppendLine(char[] chars, int length)


{


return this.AppendLine(chars, 0, length);


}




public TextBuilder AppendLine(string s, int length)


{


return this.AppendLine(s.ToCharArray(0, length), 0, length);


}


public TextBuilder AppendLine(string s, int startIndex, int length)


{


return this.AppendLine(s.ToCharArray(startIndex, length), 0, length);


}




public TextBuilder AppendLine(char[] chars, int startIndex, int length)


{


if(length < 1)return this;


if (chars == null)


{


throw new ArgumentNullException("chars");


}


if ((startIndex < 0) || (chars.Length < (startIndex + length)))


{


throw new ArgumentOutOfRangeException();


}


//取得换行符


string newLine = System.Environment.NewLine;




this.EnsureCapacityInternal(this._length + length + newLine.Length);


TextBuilder.UnsafeCopyChars(this._data, this._length, chars, startIndex, length);


this._length += length;




//添加新的一行


for(int i=0; i<newLine.Length; i++)


{


this._data[this._length++] = newLine[i];


}


this.MakeDirty();


return this;


}


#endregion




#region 清空字符


public void Clear()


{


this._length = 0;


this._data = new char[0];


this.MakeDirty();


}


#endregion




#region 从某字符串里拷贝


public void Copy(char ch)


{


this.EnsureCapacityInternal(1);


this._data[0] = ch;


this._length = 1;


this.MakeDirty();


}




public void Copy(string s)


{


this.Copy(s.ToCharArray(), 0, s.Length);


}




public void Copy(char[] chars)


{


this.Copy(chars, 0, chars.Length);


}




public void Copy(string s, int length)


{


this.Copy(s.ToCharArray(0, length), 0, length);


}




public void Copy(char[] chars, int length)


{


this.Copy(chars, 0, length);


}




public void Copy(char[] chars, int startIndex, int length)


{


if(length < 1)return;




if (chars == null)


{


throw new ArgumentNullException("chars");


}


if ((startIndex < 0) || (chars.Length < (startIndex + length)))


{


throw new ArgumentOutOfRangeException();


}


this.EnsureCapacityInternal(length);


TextBuilder.UnsafeCopyChars(this._data, 0, chars, startIndex, length);


this.MakeDirty();


this._length = length;


}




public void Copy(string s, int startIndex, int length)


{


this.Copy(s.ToCharArray(startIndex, length), 0, length);


}


#endregion




#region 删除字符


public bool Delete(int startIndex)


{


if ((startIndex < 0) || (this._data == null))


{


return false;


}


this._length = startIndex;


this.MakeDirty();


return true;


}


public bool Delete(int startIndex, int length)


{


if (((startIndex < 0) || (this._data == null)) || (startIndex > this.Length))


{


return false;


}


this.ShiftCharsLeft(this._data, startIndex, this.Length, length);


this._length -= length;


this.MakeDirty();


return true;


}


#endregion




#region 重新设置容量


private void EnsureCapacityInternal(int capacity)


{


if (this._length < capacity)


{


if (capacity > PaddingSize)


{


int num1 = PaddingSize - (capacity % PaddingSize);


capacity += num1;


}


else


{


capacity = PaddingSize;


}


char[] chArray1 = new char[capacity];


if (this._length != 0)


{


TextBuilder.UnsafeCopyChars(chArray1, 0, this._data, 0, this._length);


}


this._data = chArray1;


this._capacity = capacity;


}


}


#endregion




#region 插入字符


public void Insert(int index, char c)


{


if ((index < 0) || (index > this._length))


{


throw new ArgumentOutOfRangeException("index");


}


this.Capacity = (this._length + 1);


this.ShiftCharsRight(this._data, index, this._length, 1);


this._data[index] = c;


this._length++;


this.MakeDirty();


}






public void Insert(int index, char[] chars)


{


if (chars == null)


{


throw new ArgumentNullException("chars");


}


this.Insert(index, chars, 0, chars.Length);


}






public void Insert(int index, string s)


{


this.Insert(index, s.ToCharArray());


}




public void Insert(int index, char[] chars, int start, int length)


{


if(length < 1)return;


if (chars == null)


{


throw new ArgumentNullException("chars");


}


if ((index < 0) || (index > this._length))


{


throw new ArgumentOutOfRangeException("index");


}


this.Capacity = this._length + length;


this.ShiftCharsRight(this._data, index, this._length, length);


Array.Copy(chars, start, this._data, index, length);


this._length += length;


this.MakeDirty();


}


#endregion




#region 查找字符


public int IndexOf(char ch)


{


if (this._length != 0)


{


return TextBuilder.UnsafeIndexOf(this._data, 0, this._length, ch);


}


return -1;


}




public int IndexOf(string s)


{


return this.IndexOf(s, 0, false);


}




public int IndexOf(string s, bool ignoreCase)


{


return this.IndexOf(s, 0, ignoreCase);


}




public int IndexOf(string s, int startIndex, bool ignoreCase)


{


if (s == null)


{


throw new ArgumentNullException();


}


int num1 = s.Length;


if (num1 == 0)


{


return 0;


}


if (this._length >= num1)


{


char[] chArray1 = s.ToCharArray();


int num2 = this._length - num1;


if (!ignoreCase)


{


for (int num6 = startIndex; num6 <= num2; num6++)


{


if (TextBuilder.UnsafeCompareChars(this._data, num6, this._length - num6, chArray1, 0, num1) == 0)


{


return num6;


}


}


}


else


{


for (int num7 = startIndex; num7 <= num2; num7++)


{


if (TextBuilder.UnsafeCompareCharsIgnoreCase(this._data, num7, this._length - num7, chArray1, 0, num1) == 0)


{


return num7;


}


}


}


}


return -1;


}


public int IndexOfAny(char[] chars)


{


if (chars == null)


{


throw new ArgumentNullException();


}


if (this._length != 0)


{


int num1 = chars.Length;


for (int num3 = 0; num3 < num1; num3++)


{


int num2 = TextBuilder.UnsafeIndexOf(this._data, 0, this._length, chars[num3]);


if (num2 != -1)


{


return num2;


}


}


}


return -1;


}


#endregion




#region 判断字符是否相等


/// <summary>


/// 判断是否以某字符开头


/// </summary>


/// <param name="equalString">要判断的字符</param>


/// <returns></returns>


public bool StartWith(string equalString)


{


return this.StartWith(equalString,false);


}


public bool StartWith(string equalString,bool ignoreCase)


{


return this.InWith(0,equalString,ignoreCase);


}


/// <summary>


/// 判断字符是否相同并区分大小写


/// </summary>


/// <param name="startIndex">起始索引位置</param>


/// <param name="equalString">要判断的字符</param>


/// <returns></returns>


public bool InWith(int startIndex,string equalString)


{


return this.InWith(startIndex,equalString,false);


}


/// <summary>


/// 判断字符是否相同


/// </summary>


/// <param name="startIndex">起始索引位置</param>


/// <param name="equalString">要判断的字符</param>


/// <param name="ignoreCase">是否不区分大小写</param>


/// <returns></returns>


public bool InWith(int startIndex, string equalString,bool ignoreCase)


{


if(equalString == null || equalString.Length < 1)return false;


if(startIndex < 0)return false;


if((startIndex + equalString.Length) > this._length)return false;




if(ignoreCase)


{


return (UnsafeCompareCharsIgnoreCase(this._data,startIndex,equalString.Length,equalString.ToCharArray(),0,equalString.Length) == 0);


}


else


{


return (UnsafeCompareChars(this._data,startIndex,equalString.Length,equalString.ToCharArray(),0,equalString.Length) == 0);


}




}




/// <summary>


/// 判断是否以某字符结尾


/// </summary>


/// <param name="equalString">要判断的字符</param>


/// <returns></returns>


public bool EndWith(string equalString)


{


return this.EndWith(equalString,false);


}


public bool EndWith(string equalString,bool ignoreCase)


{


if(equalString == null || equalString.Length < 1)return false;


if(equalString.Length > this._length)return false;




return this.InWith((this._length - equalString.Length),equalString,ignoreCase);


}


#endregion




#region 从后面查找字符


public int LastIndexOf(char ch)


{


if (this._length != 0)


{


return TextBuilder.UnsafeLastIndexOf(this._data, 0, this._length, ch);


}


return -1;


}




public int LastIndexOf(string s)


{


return this.LastIndexOf(s, this._length, false);


}




public int LastIndexOf(string s, bool ignoreCase)


{


return this.LastIndexOf(s, this._length, ignoreCase);


}


public int LastIndexOf(string s, int startIndex, bool ignoreCase)


{


if (s == null)


{


throw new ArgumentNullException();


}


int num1 = s.Length;


if (num1 == 0)


{


return 0;


}


if (this._length >= num1)


{


char[] chArray1 = s.ToCharArray();


int num2 = Math.Min(this._length - num1, startIndex);


if (!ignoreCase)


{


for (int num6 = num2; num6 >= 0; num6--)


{


if (TextBuilder.UnsafeCompareChars(this._data, num6, this._length - num6, chArray1, 0, num1) == 0)


{


return num6;


}


}


}


else


{


for (int num7 = num2; num7 >= 0; num7--)


{


if (TextBuilder.UnsafeCompareCharsIgnoreCase(this._data, num7, this._length - num7, chArray1, 0, num1) == 0)


{


return num7;


}


}


}


}


return -1;


}


public int LastIndexOfAny(char[] chars)


{


if (chars == null)


{


throw new ArgumentNullException();


}


if (this._length != 0)


{


int num1 = chars.Length;


for (int num3 = 0; num3 < num1; num3++)


{


int num2 = TextBuilder.UnsafeLastIndexOf(this._data, 0, this._length, chars[num3]);


if (num2 != -1)


{


return num2;


}


}


}


return -1;


}


#endregion




#region 获取某部分字符


public string SubString(int startIndex, int length)


{


if(startIndex < 0 || length < 1)return string.Empty;




length = Math.Min(length,this._length - startIndex);


return new string(this.ToCharArray(startIndex, length));


}


public string SubStr(int startIndex, int endIndex)


{


if(startIndex < 0 || endIndex < startIndex)return string.Empty;




return SubString(startIndex, (endIndex - startIndex) + 1);


}


public override string ToString()


{


if (this._cachedString == null)


{


if (this._length != 0)


{


this._cachedString = new string(this._data, 0, this._length);


}


else


{


this._cachedString = string.Empty;


}


}


return this._cachedString;


}


#endregion




#region 返回字符


public char[] ToCharArray()


{


return this.ToCharArrayInternal(0, this._length);


}




public char[] ToCharArray(int startIndex, int length)


{


if ((startIndex < 0) || (this._length < (startIndex + length)))


{


throw new ArgumentOutOfRangeException();


}


return this.ToCharArrayInternal(startIndex, length);


}




private char[] ToCharArrayInternal(int startIndex, int length)


{


if (length == 0)


{


return new char[0];


}


char[] chArray1 = new char[length];


TextBuilder.UnsafeCopyChars(chArray1, 0, this._data, startIndex, length);


return chArray1;


}


#endregion




#region 替换字符


/// <summary>


/// 替换字符


/// </summary>


/// <param name="find">要查找的字符</param>


/// <param name="replacement">要替换的字符</param>


public void Replace(string find, string replacement)


{


this.Replace(find,replacement,0);


}


/// <summary>


/// 替换字符


/// </summary>


/// <param name="find">要查找的字符</param>


/// <param name="replacement">要替换的字符</param>


/// <param name="startIndex">起始位置</param>


public void Replace(string find, string replacement, int startIndex)


{


this.Replace(find,replacement,startIndex,false,0);


}


/// <summary>


/// 替换字符


/// </summary>


/// <param name="find">要查找的字符</param>


/// <param name="replacement">要替换的字符</param>


/// <param name="ignoreCase">是否不区分大小字</param>


public void Replace(string find, string replacement, bool ignoreCase)


{


this.Replace(find,replacement,0,ignoreCase,0);


}


/// <summary>


/// 替换字符


/// </summary>


/// <param name="find">要查找的字符</param>


/// <param name="replacement">要替换的字符</param>


/// <param name="startIndex">起始位置</param>


/// <param name="ignoreCase">是否不区分大小字</param>


public void Replace(string find, string replacement, int startIndex, bool ignoreCase)


{


this.Replace(find,replacement,startIndex,ignoreCase,0);


}


/// <summary>


/// 替换字符


/// </summary>


/// <param name="find">要查找的字符</param>


/// <param name="replacement">要替换的字符</param>


/// <param name="startIndex">起始位置</param>


/// <param name="ignoreCase">是否不区分大小字</param>


/// <param name="replaceCount">替换字数.如果小于1则替换全部</param>


public void Replace(string find, string replacement, int startIndex, bool ignoreCase, int replaceCount)


{


if (find == null || replacement == null)


{


throw new ArgumentNullException();


}


if(find.Length > this._length)return;




//取得缓存数组的数量


int bufferlen = replacement.Length - find.Length;


if(bufferlen > 0)


{


bufferlen = this._length + (this._length / find.Length) * bufferlen;


}


else


{


bufferlen = this._length;


}


char[] buffer = new char[0];


int c = 0;


int index = 0,sourceIndex = 0,descIndex = 0;


while(true)


{


index = IndexOf(find,startIndex,ignoreCase);


if(index >= 0)


{


//第一次则初始化缓存数组


if(c == 0)buffer = new char[bufferlen];


//复制原始数据[不包括已查找到的数据]


Array.Copy(this._data,sourceIndex,buffer,descIndex,(index - sourceIndex));


//复制新数据


descIndex += (index - sourceIndex);


if(replacement.Length > 0)


{




Array.Copy(replacement.ToCharArray(),0,buffer,descIndex,replacement.Length);


descIndex += replacement.Length;


}




//移动指针


sourceIndex = index + find.Length;


startIndex = sourceIndex;




c ++;


if(startIndex > this._length || (replaceCount > 0 && c >= replaceCount))break;


}


else


{


break;


}


}


if(c > 0)


{


if(startIndex < this._length)


{


//拷贝后面的数据


Array.Copy(this._data,sourceIndex,buffer,descIndex,(this._length - sourceIndex));


descIndex += (this._length - sourceIndex);


}


this._data = buffer;


this._length = descIndex;


this.MakeDirty();


}


}


#endregion




#region 私有处理函数


private void MakeDirty()


{


this._cachedString = null;


}




private void ShiftCharsLeft(char[] chars, int startIndex, int endIndex, int shiftAmount)


{


Array.Copy(chars, startIndex + shiftAmount, chars, startIndex, endIndex - (shiftAmount + startIndex));


}






private void ShiftCharsRight(char[] chars, int startIndex, int endIndex, int shiftAmount)


{


Array.Copy(chars, startIndex, chars, startIndex + shiftAmount, endIndex - startIndex);


}




private static unsafe int UnsafeCompareChars(char[] chars1, int startIndex1, int length1, char[] chars2, int startIndex2, int length2)


{


fixed (char* chRef1 = chars1)


{


fixed (char* chRef2 = chars2)


{


char* chPtr1 = chRef1 + startIndex1;


char* chPtr2 = chRef2 + startIndex2;


int num1 = 0;


int num2 = 0;


while ((num1 < length1) && (num2 < length2))


{


if (chPtr1[0] != chPtr2[0])


{


return (chPtr1[0] - chPtr2[0]);


}


num1++;


num2++;


chPtr1++;


chPtr2++;


}


if (num1 == num2)


{


return 0;


}


if (num1 < length1)


{


return 1;


}


return -1;


}


}


}




private static unsafe int UnsafeCompareCharsIgnoreCase(char[] chars1, int startIndex1, int length1, char[] chars2, int startIndex2, int length2)


{


fixed (char* chRef1 = chars1)


{


fixed (char* chRef2 = chars2)


{


char* chPtr1 = chRef1 + startIndex1;


char* chPtr2 = chRef2 + startIndex2;


int num1 = 0;


int num2 = 0;


while ((num1 < length1) && (num2 < length2))


{


if (char.ToUpper(chPtr1[0]) != char.ToUpper(chPtr2[0]))


{


return (chPtr1[0] - chPtr2[0]);


}


num1++;


num2++;


chPtr1++;


chPtr2++;


}


if (num1 == num2)


{


return 0;


}


if (num1 < length1)


{


return 1;


}


return -1;


}


}


}




private static unsafe void UnsafeCopyBytes(byte[] destBytes, int destStartIndex, byte[] srcBytes, int srcStartIndex, int length)


{


fixed (byte* numRef1 = destBytes)


{


fixed (byte* numRef2 = srcBytes)


{


byte* numPtr1 = numRef1 + destStartIndex;


byte* numPtr2 = numRef2 + srcStartIndex;


for (int num1 = 0; num1 < length; num1++)


{


*(numPtr1++) = *(numPtr2++);


}


}


}


}




private static unsafe void UnsafeCopyChars(char[] destChars, int destStartIndex, char[] srcChars, int srcStartIndex, int length)


{


fixed (char* chRef1 = destChars)


{


fixed (char* chRef2 = srcChars)


{


char* chPtr1 = chRef1 + destStartIndex;


char* chPtr2 = chRef2 + srcStartIndex;


for (int num1 = 0; num1 < length; num1++)


{


chPtr1[0] = chPtr2[0];


chPtr1++;


chPtr2++;


}


}


}


}




private static unsafe int UnsafeIndexOf(char[] chars, int startIndex, int length, char ch)


{


fixed (char* chRef1 = chars)


{


char* chPtr1 = chRef1 + startIndex;


int num1 = startIndex;


while (num1 < length)


{


if (chPtr1[0] == ch)


{


return num1;


}


num1++;


chPtr1++;


}


}


return -1;


}


private static unsafe int UnsafeLastIndexOf(char[] chars, int startIndex, int length, char ch)


{


fixed (char* chRef1 = chars)


{


char* chPtr1 = chRef1 + (length - 1);


int num1 = length - 1;


while (num1 >= startIndex)


{


if (chPtr1[0] == ch)


{


return num1;


}


num1--;


chPtr1--;


}


}


return -1;


}




private static unsafe void UnsafeShiftCharsLeft(char[] chars, int startIndex, int endIndex, int shiftAmount)


{


fixed (char* chRef1 = chars)


{


char* chPtr1 = chRef1 + startIndex;


char* chPtr2 = (chRef1 + endIndex) - (shiftAmount * 2);


while (chPtr1 < chPtr2)


{


chPtr1[0] = chPtr1[shiftAmount];


chPtr1++;


}


}


}


private static unsafe void UnsafeShiftCharsRight(char[] chars, int startIndex, int endIndex, int shiftAmount)


{


fixed (char* chRef1 = chars)


{


char* chPtr1 = (chRef1 + startIndex) + (shiftAmount * 2);


for (char* chPtr2 = ((chRef1 + endIndex) + (shiftAmount * 2)) - (1 * 2); chPtr2 >= chPtr1; chPtr2--)


{


chPtr2[0] = *(chPtr2 - shiftAmount);


}


}


}


#endregion




#region 属性


public bool IsEmpty


{


get


{


return (this._length == 0);


}


}


public char this[int index]


{


get


{


if ((index < 0) || (index >= this._length))


{


throw new ArgumentOutOfRangeException();


}


return this._data[index];


}


set


{


if ((index < 0) || (index >= this._length))


{


throw new ArgumentOutOfRangeException();


}


this._data[index] = value;


this.MakeDirty();


}


}


/// <summary>


/// 设置或返回初始容量


/// </summary>


public int Capacity


{


get


{


return _capacity;


}


set


{


if (value <= 0)


{


throw new ArgumentOutOfRangeException();


}


this.EnsureCapacityInternal(value);


}


}


/// <summary>


/// 设置或返回当前存储字符的长度


/// </summary>


public int Length


{


get


{


return this._length;


}


set


{


if (value < 0)


{


throw new ArgumentOutOfRangeException();


}


if (this._length > value)


{


this._length = value;


this.MakeDirty();


}


}


}


#endregion




// Fields


private string _cachedString;


private char[] _data;


private int _length;


private int _capacity;


private const int PaddingSize = 0x10;


}


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: