【问题标题】:Replace only 'n' occurences of a substring in a string in C#在 C# 中仅替换字符串中出现的“n”个子字符串
【发布时间】:2019-03-22 06:53:19
【问题描述】:

我有一个输入字符串,比如 -

阿布达巴布

如何将子字符串 "ab"2nd3rd后续出现 替换为任意随机字符串,例如 "x" 保持原字符串完好无损。本例中的示例 -

第一个输出 - xbdabab 第二个输出 - abbdxab 第三个输出 - abbdabx 等等...

我尝试过使用 Regex 之类的 -

int occCount = Regex.Matches("abbdabab", "ab").Count;

if (occCount > 1)
{
    for (int i = 1; i <= occCount; i++)
    {
        Regex regReplace = new Regex("ab");
        string modifiedValue = regReplace.Replace("abbdabab", "x", i);
        //decodedMessages.Add(modifiedValue);
    }
 }

当计数器i 的值为1 时,我能够获得第一个输出,但无法获得后续结果。是否有任何 重载 Replace 方法可以实现这一目标?或者谁能​​帮我指出我可能出错的地方?

【问题讨论】:

    标签: c# regex string substring


    【解决方案1】:

    你可以试试IndexOf 代替正则表达式:

    string source = "abbdabab";
    string toFind = "ab";
    string toSet = "X";
    
    for (int index = source.IndexOf(toFind); 
         index >= 0; 
         index = source.IndexOf(toFind, index + 1)) {
      string result = source.Substring(0, index) + 
                      toSet + 
                      source.Substring(index + toFind.Length);
    
      Console.WriteLine(result);
    }
    

    结果:

    Xbdabab
    abbdXab
    abbdabX
    

    【讨论】:

      【解决方案2】:

      您可以使用StringBuilder

      string s = "abbdabab";
      var matches = Regex.Matches(s, "ab");
      StringBuilder sb = new StringBuilder(s);
      var m = matches[0]; // 0 for first output, 1 for second output, and so on
      sb.Remove(m.Index, m.Length);
      sb.Insert(m.Index, "x");
      var result = sb.ToString();
      Console.WriteLine(result);
      

      【讨论】:

      • 不知道 'Regex.Matches' 的 'Index' 和 'Length' 属性它是如此简单和优雅。非常感谢。
      【解决方案3】:

      您可以使用动态构建的正则表达式直接与regex.Replace 一起使用:

      var s = "abbdabab";
      var idx = 1; // First = 1, Second = 2
      var search = "ab";
      var repl = "x";
      var pat = new Regex($@"(?s)((?:{search}.*?){{{idx-1}}}.*?){search}"); // ((?:ab.*?){0}.*?)ab
      Console.WriteLine(pat.Replace(s, $"${{1}}{repl}", 1));
      

      C# demo

      模式看起来像 ((?:ab.*?){0}.*?)ab 并且会匹配

      • (?s) - RegexOptions.Singleline 使 . 也匹配换行符
      • ((?:ab.*?){0}.*?) - 第 1 组(稍后,此值将通过 ${1} 反向引用放回结果中)
        • (?:ab.*?){0} - ab 出现 0 次,后跟尽可能少的 0+ 个字符
        • .*? - 尽可能少的任何 0+ 个字符
      • ab - 搜索字符串/模式。

      pat.Replace 的最后一个参数是1,因此只能替换第一个匹配项。

      如果search是文字文本,则需要使用var search = Regex.Escape("a+b");

      如果repl 可以有$,则添加repl = repl.Replace("$", "$$");

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-07
        • 1970-01-01
        • 1970-01-01
        • 2014-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多