【问题标题】:Replace {#Text} and {$Text} in a string, in a performant way以高效的方式替换字符串中的 {#Text} 和 {$Text}
【发布时间】:2010-10-15 21:28:34
【问题描述】:

注意:这不是一个简单的字符串替换问题。

SomethingBlahBlah 可以是#SomeThingOtherthanThis

我的情况如下,我有一个大字符串(300B),其中包含 {#String} 和 {$String}。

为了更具体的 {#SomethingBlahBlah} 和 {$SomeOtherThingBlahBlah},所以在正则表达式 {#w+} 和 {$w+}

我的第一个问题是,正则表达式是唯一的方法吗?我想要一个字符串替换解决方案或类似的解决方案,其次,如果是的话,有没有办法只做一个编译的正则表达式并做一次通过?

Linq 能否提供帮助?

【问题讨论】:

  • 为什么不能使用 String.Replace 方法?
  • 我认为小于 1KB 的字符串是 small 字符串。
  • kzen,因为它在每次替换时分配。
  • 你必须处理多少个不同的“某事”值键(在原始字符串中)? “只有一两个”可能值的解决方案可能与“几十个”的解决方案不同。

标签: c# regex linq


【解决方案1】:

对于大字符串,以及几个不同的替换,我建议使用 StringBuilder。

StringBuilder sb = new StringBuilder(input);
sb.Replace("{$String}", "Real Value");
sb.Replace("{$SomeOtherThingBlahBlah}", "Another Real Value");
return sb.ToString();

操作将在内存中发生,并且在调用 ToString() 之前不会分配新字符串。

【讨论】:

    【解决方案2】:

    IndexOf 与正则表达式:使用Stopwatch 进行测试,使用 500~ 长度的字符串进行 100000 次迭代。

    方法索引

    public static string Re(string str)
    {
        int strSIndex = -1;
        int strEIndex = -1;
    
        strSIndex = str.IndexOf("{#");
        if (strSIndex == -1) strSIndex = str.IndexOf("{$");
        if (strSIndex == -1) return str;
    
        strEIndex = str.IndexOf("}");
        if (strEIndex == -1) return str;
    
        if (strEIndex < strSIndex)
        {
            strSIndex = str.IndexOf("{$");
            if (strSIndex == -1) return str;
        }
    
        str = str.Substring(0, strSIndex) + str.Substring(strEIndex + 1);
    
        return Re(str);
    }
    

    正则表达式方法

    Regex re = new Regex(@"\{(?:#|\$)(\w+)}", RegexOptions.Compiled);
    re.Replace(str, "");
    

    结果(很少替换):

    Fn: IndexOf
    Ticks: 1181967
    
    Fn: Regex
    Ticks: 1482261
    

    请注意,正则表达式被设置为在迭代之前编译。

    结果(大量替换):

    Fn: Regex
    Ticks: 19136772
    
    Fn: IndexOf
    Ticks: 37457111
    

    【讨论】:

    • @tinifni 回答中的正则表达式。
    • 谢谢!这正是我想要的完全 :-)
    【解决方案3】:

    您可以使用以下之一:

    选项 1

    正则表达式:

    \{(?:#|\$)(\w+)}
    

    文字:

    {#SomethingBlahBlah} and {$SomeOtherThingBlahBlah}
    

    返回:

    Result 1
    
       1. SomethingBlahBlah
    
    Result 2
    
       1. SomeOtherThingBlahBlah
    

    选项 2

    正则表达式:

    (\{(?:#|\$)(?:\w+)})
    

    文字:

    {#SomethingBlahBlah} and {$SomeOtherThingBlahBlah}
    

    返回:

    Result 1
    
       1. {#SomethingBlahBlah}
    
    Result 2
    
       1. {$SomeOtherThingBlahBlah}
    

    【讨论】:

    • 没问题。不过,您可能想调查 Matt Brunell 的答案。找到适合您的答案后,不要忘记接受答案。编码愉快!
    【解决方案4】:

    Regex 需要更多时间来替换文本,而不是使用 String.Replace 方法。但是正则表达式通过文本操作为您提供了巨大的力量。 LINQ 没有使用字符串的直接方法。它只能使用现有的功能。

    【讨论】:

      【解决方案5】:
      String.Replace("SomethingBlahBlah", "SomeOtherThingBlahBlah")
      

      编辑:刚刚在thread 中找到了 Jon Skeet 的一个很好的答案。

      【讨论】:

      • 这将是一个两遍算法:一次用于替换{#Text},另一次用于替换{$Text}。 OP 明确要求一次性解决方案。
      • 我不认为“有没有办法只做一个编译的正则表达式并做一次传递?”有资格作为一次性解决方案的明确请求......
      猜你喜欢
      • 2014-01-25
      • 1970-01-01
      • 1970-01-01
      • 2010-09-27
      • 2014-11-12
      • 1970-01-01
      • 1970-01-01
      • 2015-05-06
      • 1970-01-01
      相关资源
      最近更新 更多