是否需要在StringBuilder中替换字符串之前进行检查(使用“Contains”或“IndexOf”等函数)?

时间:2011-06-21 10:06:56

标签: c# stringbuilder

C#中是否有任何方法IndexOf或Contains。以下是代码:

var sb = new StringBuilder(mystring);
sb.Replace("abc", "a");
string dateFormatString = sb.ToString();

if (sb.ToString().Contains("def"))
{
    sb.Replace("def", "aa");
}


if (sb.ToString().Contains("ghi"))
{
    sb.Replace("ghi", "assd");
}

你可能已经注意到我一次又一次地使用ToString(),我想避免它,因为它每次都在创建新的字符串。你能帮帮我怎样才能避免它?

4 个答案:

答案 0 :(得分:19)

如果StringBuilder 包含“def”,那么执行替换不会导致任何问题,所以只需使用:

var sb = new StringBuilder(mystring);
sb.Replace("abc", "a");
sb.Replace("def", "aa");
sb.Replace("ghi", "assd");

答案 1 :(得分:5)

StringBuilder中没有这样的方法,但您不需要Contains测试。您可以这样写:

 sb.Replace("abc", "a");
 sb.Replace("def", "aa");
 sb.Replace("ghi", "assd");

如果未找到Replace的第一个参数中的字符串,则对Replace的调用是空操作 - 正是您想要的。

文档说明:

  

使用另一个指定的字符串替换此实例中指定字符串的所有匹配项。

你读这篇文章的方式是,当没有出现时,什么也没做。

答案 2 :(得分:3)

您可以编写一个将方法扩展到StringBuilder对象的类。在这里,我向StringBuilder类添加了IndexOf,Substring和其他方法。把这个课程放在你的项目中。

using System;
using System.Text;

namespace Helpers
{
    /// <summary>
    /// Adds IndexOf, IsStringAt, AreEqual, and Substring to all StringBuilder objects.
    /// </summary>
    public static class StringBuilderExtension
    {
        // Adds IndexOf, Substring, AreEqual to the StringBuilder class.
        public static int IndexOf(this StringBuilder theStringBuilder,string value)
        {
            const int NOT_FOUND = -1;
            if (theStringBuilder == null)
            {
                return NOT_FOUND;
            }
            if (String.IsNullOrEmpty(value))
            {
                return NOT_FOUND;
            }
            int count = theStringBuilder.Length;
            int len = value.Length;            
            if (count < len)
            {
                return NOT_FOUND;
            }
            int loopEnd = count - len + 1;
            for (int loop = 0; loop < loopEnd; loop++)
            {
                bool found = true;
                for (int innerLoop = 0; innerLoop < len; innerLoop++)
                {
                    if (theStringBuilder[loop + innerLoop] != value[innerLoop])
                    {
                        found = false;
                        break;
                    }
                }
                if (found)
                {
                    return loop;
                }
            }
            return NOT_FOUND;
        }
        public static int IndexOf(this StringBuilder theStringBuilder, string value,int startPosition)
        {
            const int NOT_FOUND = -1;
            if (theStringBuilder == null)
            {
                return NOT_FOUND;
            }
            if (String.IsNullOrEmpty(value))
            {
                return NOT_FOUND;
            }
            int count = theStringBuilder.Length;
            int len = value.Length;
            if (count < len)
            {
                return NOT_FOUND;
            }
            int loopEnd = count - len + 1;
            if (startPosition >= loopEnd)
            {
                return NOT_FOUND;
            }
            for (int loop = startPosition; loop < loopEnd; loop++)
            {
                bool found = true;
                for (int innerLoop = 0; innerLoop < len; innerLoop++)
                {
                    if (theStringBuilder[loop + innerLoop] != value[innerLoop])
                    {
                        found = false;
                        break;
                    }
                }
                if (found)
                {
                    return loop;
                }
            }
            return NOT_FOUND;
        }
        public static string Substring(this StringBuilder theStringBuilder, int startIndex, int length)
        {
            return theStringBuilder == null ? null : theStringBuilder.ToString(startIndex, length);
        }
        public static bool AreEqual(this StringBuilder theStringBuilder, string compareString)
        {
            if (theStringBuilder == null)
            {
                return compareString == null;
            }
            if (compareString == null)
            {
                return false;
            }
            int len = theStringBuilder.Length;
            if (len != compareString.Length)
            {
                return false;
            }
            for (int loop = 0; loop < len; loop++)
            {
                if (theStringBuilder[loop] != compareString[loop])
                {
                    return false;
                }
            }
            return true;            
        }
        /// <summary>
        /// Compares one string to part of another string.
        /// </summary>
        /// <param name="haystack"></param>
        /// <param name="needle">Needle to look for</param>
        /// <param name="position">Looks to see if the needle is at position in haystack</param>
        /// <returns>Substring(theStringBuilder,offset,compareString.Length) == compareString</returns>
        public static bool IsStringAt(this StringBuilder haystack, string needle,int position)
        {
            if (haystack == null)
            {
                return needle == null;
            }
            if (needle == null)
            {
                return false;
            }
            int len = haystack.Length;
            int compareLen = needle.Length;
            if (len < compareLen + position)
            {
                return false;
            }
            for (int loop = 0; loop < compareLen; loop++)
            {
                if (haystack[loop+position] != needle[loop])
                {
                    return false;
                }
            }
            return true;
        }

    }
}

答案 3 :(得分:2)

恕我直言,你不必在这种情况下使用StringBuilder ...在循环中使用时,StringBuilder更有用。就像微软在In this article

中所说的那样
  

String对象是不可变的。一切   你使用其中一种方法的时间   System.String类,你创建一个新的   内存中的字符串对象,其中   需要新的空间分配   那个新对象。在哪些情况下   你需要重复表演   对字符串的修改,   与创建相关的开销   新的String对象可能很昂贵。该   System.Text.StringBuilder类可以   用于修改字符串时使用   没有创建新对象。对于   例如,使用StringBuilder类   可以提高性能   将许多字符串连接在一起   循环

因此,您可以使用String并避免使用ToString()...