我需要一个与StringBuilder类一起使用的不区分大小写的Replace方法

时间:2010-07-29 21:14:54

标签: .net string replace stringbuilder case-insensitive

我需要代码用于Replace类的不区分大小写的StringBuilder方法。代码应该与现有的StringBuilder一起使用。扩展方法实现会很好。

以下是我打算如何使用该方法:

    [TestMethod]
    public void StringBuilder_Replace_TTD() {

        StringBuilder oRequestText = new StringBuilder(File.ReadAllText("Customer.xml"));

        Customer oCustomer = new Customer(null);

        foreach (FieldIndex iField in Enum.GetValues(typeof(FieldIndex))) {

            oRequestText.Replace("{" iField.ToString() + "}", oCustomer[iField]);

        }

        Debug.WriteLine(oRequestText.ToString());
    }

4 个答案:

答案 0 :(得分:3)

StringBuilder在搜索/替换文本时不支持使用IComparer(事实上,根本没有搜索支持)。你可以尝试滚动逐个字符的版本,但这会很复杂,但仍然可能表现不佳。

根据您的使用案例,我建议使用字符串而不是StringBuilder,并使用string.IndexOf()在输入字符串中找到您要替换的位置 - 这支持不区分大小写搜索。找到所有替换区域后,创建一个StringBuilder,然后复制每个区域 - 用所需的替换值替换找到的文本。

编辑:据推测,您希望使用StringBuilder替换,以避免分配额外的字符串并因此而影响性能。但是,替换 {/ 1}}缓冲区中的文本实际上可能更昂贵 - 特别是如果替换字符串的长度与它们要替换的源字符串的长度不同。每次替换都要求字符向前或向后移动,具体取决于替换文本是更短还是更长。像这样执行内存块移动会很昂贵。

答案 1 :(得分:2)

来自:http://blogs.msdn.com/b/btine/archive/2005/03/22/400667.aspx

string Replace( string expr, string find, string repl, bool bIgnoreCase )  
{
// Get input string length
       int exprLen = expr.Length;
       int findLen = find.Length;

       // Check inputs    
       if( 0 == exprLen || 0 == findLen || findLen > exprLen )    
              return expr;

       // Use the original method if the case is required    
       if( !bIgnoreCase )
              return expr.Replace( find, repl );

       StringBuilder sbRet = new StringBuilder( exprLen );

       int pos = 0;              
       while( pos + findLen <= exprLen )    
       {    
              if( 0 == string.Compare( expr, pos, find, 0, findLen, bIgnoreCase ) )    
              {    
                     // Add the replaced string    
                     sbRet.Append( repl );    
                     pos += findLen;    
                     continue;    
              }

              // Advance one character    
              sbRet.Append( expr, pos++, 1 );    
       }

       // Append remaining characters    
       sbRet.Append( expr, pos, exprLen-pos );

       // Return string    
       return sbRet.ToString();    
}

答案 2 :(得分:0)

在你想要的例子中(伪代码):

StringBuilder oRequestText = ...;
For all fields do replace on oRequestText;
Debug.WriteLine(oRequestText.ToString());

由于在此之后您实际上没有使用StringBuilder,因此与

没有任何功能差异
StringBuilder oRequestText = ...;
string strRequest = oRequestText.ToString();
For all fields do replace on strRequest;
Debug.WriteLine(strRequest);

字符串的正常替换函数应该可以轻松支持您想要执行的操作。

我假设你真的想再次使用StringBuilder。但是,最简单的做.ToString(),替换字符串,然后用字符串重新加载StringBuilder。

答案 3 :(得分:0)

我使用RegEx替换方法,但这意味着从StribgBuilder转换为字符串

oRequestText = new StringBuilder(Regex.Replace(oRequestText.ToString(), "{" iField.ToString() + "}", oCustomer[iField], RegexOptions.IgnoreCase)));