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

发布于 2024-09-12 05:35:52 字数 595 浏览 6 评论 0原文

我需要 StringBuilder 类的不区分大小写的 Replace 方法的代码。该代码应该与现有的 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());
    }

I need code for a case-insensitive Replace method for the StringBuilder class. The code should work with the existing StringBuilder. An extension method implementation would be nice.

Following is how I plan to use the method:

    [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());
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

嘦怹 2024-09-19 05:35:52

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

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

编辑:大概您希望使用 StringBuilder 进行替换,以避免分配额外的字符串并导致性能下降。然而,替换StringBuilder缓冲区内的文本实际上可能会更昂贵 - 特别是如果替换字符串的长度与它们要替换的源字符串的长度不同。每次替换都要求将字符向前或向后移动,具体取决于替换文本是较短还是较长。像这样执行内存块移动将是昂贵的。

StringBuilder doesn't support using an IComparer when search/replacing text (in fact, there is no search support at all). You could try rolling a character-by-character version, but that will be complicated and may still perform poorly.

Based on your use case, I would suggest using a string rather than StringBuilder, and using string.IndexOf() to locate the positions in the input string where you are going to do replacement - which support case insensitive search. Once you've located all of the replacement regions, create a StringBuilder and then copy each region - replacing found text with the desired replacement values.

EDIT: Presumably you are looking to use replacement with a StringBuilder to avoid allocating additional strings and incurring the performance hit for doing so. However, replacing text within the buffer of a StringBuilder could actually be more expensive - particularly if the replacement strings are of different length than the source string they are replacing. Each replacement requires that characters be shifted forward or backwards depending on whether the replacing text is shorter or longer. Performing memory block moves like this will be expensive.

水水月牙 2024-09-19 05:35:52

来自: 链接

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();    
}

From: Link

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();    
}
以可爱出名 2024-09-19 05:35:52

在您的示例中,您想要执行以下操作(以伪代码):

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 可能仍然是最简单的。

In your example you want to do (in pseudo code):

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

Since you're not actually using the StringBuilder after this there is no functional difference with

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

The normal replace functions for strings should easily support what you want to do.

I'm assuming in your real situation you do want to use the StringBuilder again. But it's probably still easiest to do a .ToString(), replace on the string, and then reload the StringBuilder with the string.

心清如水 2024-09-19 05:35:52

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

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

I'd use the RegEx replace method, but it means converting from a StribgBuilder to a string

oRequestText = new StringBuilder(Regex.Replace(oRequestText.ToString(), "{" iField.ToString() + "}", oCustomer[iField], RegexOptions.IgnoreCase)));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文