【问题标题】:Suggest implementation of String.Replace(string oldValue, Func<string> newValue) function建议实现 String.Replace(string oldValue, Func<string> newValue) 函数
【发布时间】:2011-12-14 18:51:45
【问题描述】:

这个任务最优雅的解决方案是什么:

有一个模板字符串,例如:"&lt;CustomAction Id=&lt;newGuid&gt; /&gt;&lt;CustomAction Id=&lt;newGuid&gt; /&gt;",我需要用不同的Guid替换&lt;newGuid&gt;

概括问题:

.Net 字符串类具有 Replace 方法,该方法采用 2 个参数:字符或字符串类型的 oldValue 和 newValue。问题是 newValue 是静态字符串(不是返回字符串的函数)。

有我的简单实现:

public static string Replace(this string str, string oldValue, Func<String> newValueFunc)
    {      
      var arr = str.Split(new[] { oldValue }, StringSplitOptions.RemoveEmptyEntries);
      var expectedSize = str.Length - (20 - oldValue.Length)*(arr.Length - 1);
      var sb = new StringBuilder(expectedSize > 0 ? expectedSize : 1);
      for (var i = 0; i < arr.Length; i++)
      {
        if (i != 0)
          sb.Append(newValueFunc());
        sb.Append(arr[i]);
      }
      return sb.ToString();
    }

你能提出更优雅的解决方案吗?

【问题讨论】:

  • Regex.Replace 有类似的签名。可能会更好用。
  • Regex.Replace 让您指定回调,但您必须转义搜索字符串。
  • 终于明白他的意思了,他希望每次替换出现都是函数调用结果的不同值...问题没有正确编写,没有示例说明解决方案应该如何工作。

标签: c# .net


【解决方案1】:

我认为是时候总结一下以避免错误的答案......

leppieHenk Holterman 提出了最优雅的解决方案:

public static string Replace(this string str, string oldValue, Func<string> newValueFunc)
{
  return Regex.Replace( str,
                        Regex.Escape(oldValue),
                        match => newValueFunc() );
} 

【讨论】:

  • 这个答案不起作用。试试"t.e.s.t.".Replace(".", () =&gt; "\\\\")"t.e.s.t.".Replace(".", () =&gt; "x")。返回应该类似于:return Regex.Replace(str, Regex.Escape(oldValue), match =&gt; newValueFunc());.
  • @Enigmativity,哎呀)。感谢您的评论。
  • 我不明白,这不是 string.Replace 所做的吗?用另一个字符串替换出现的字符串?
  • @MarcelValdez - 这是使用Func&lt;string&gt; 为找到的字符串的每次出现生成不同的替换,这是这个问题的重点。
  • 是的,我明白了,但问题一开始就没有很好地表述。 IMO,您不应该对“重新阅读”问题的所有答案都投反对票,除非问题非常清楚,否则只会令人反感。每个人都回答了错误的问题,因为它的表述不正确。
【解决方案2】:

这对我有用:

public static string Replace(this string str, string oldValue,
    Func<String> newValueFunc)
{      
    var arr = str.Split(new[] { oldValue }, StringSplitOptions.None);
    var head = arr.Take(1);
    var tail =
        from t1 in arr.Skip(1)
        from t2 in new [] { newValueFunc(), t1 }
        select t2;
    return String.Join("", head.Concat(tail));
}

如果我从这个开始:

int count = 0;
Func<string> f = () => (count++).ToString();
Console.WriteLine("apple pie is slappingly perfect!".Replace("p", f));

然后我得到这个结果:

a01le 2ie is sla34ingly 5erfect!

【讨论】:

  • 是的,它有效,这正是我想要的,但 leppie 和 HenkHolterman 建议的 Regex.Replace 更优雅。
  • 是的,你是对的 - RegEx 方法是最好的 - 当它有效时。你需要检查我把答案的评论。
【解决方案3】:

使用

Regex.Replace(String, MatchEvaluator)

using System;
using System.Text.RegularExpressions;

class Sample {
//  delegate string MatchEvaluator (Match match);
    static public void Main(){

        string str = "<CustomAction Id=<newGuid> /><CustomAction Id=<newGuid> />";
        MatchEvaluator myEvaluator = new MatchEvaluator(m => newValueFunc());
        Regex regex = new Regex("newGuid");//OldValue
        string newStr = regex.Replace(str, myEvaluator);
        Console.WriteLine(newStr);
    }
    public static string newValueFunc(){
        return "NewGuid";
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 2022-11-12
    • 2014-12-05
    • 1970-01-01
    相关资源
    最近更新 更多