如何替换.NET中字符串的"第一个实例"?

时间:2020-03-06 14:47:52  来源:igfitidea点击:

我想替换给定字符串中的第一个匹配项。

如何在.NET中完成此操作?

解决方案

看一下Regex.Replace。

Regex.Replace,尤其是RegEx.Replace(string,string,int),可能正是我们想要的。 that或者String.IndexOf将为我们提供索引,然后我们可以使用所需的新文本剪切并重建字符串。

演示后者的示例(@David Humpohl首次演示):

string str = "Hello WorldWorld";

str = ReplaceFirst(str, "World", "StackOverflow ");

...

string ReplaceFirst(string text, string search, string replace)
{
    int pos = text.IndexOf(search);
    if (pos >= 0)
    {
        return text.Substring(0, pos) + replace + text.Substring(pos + search.Length);
    }
    return text;
}

string ReplaceFirst(string text, string search, string replace)
{
  int pos = text.IndexOf(search);
  if (pos < 0)
  {
    return text;
  }
  return text.Substring(0, pos) + replace + text.Substring(pos + search.Length);
}

例子:

string str = "The brown brown fox jumps over the lazy dog";

str = ReplaceFirst(str, "brown", "quick");

编辑:正如@itsmatt所提到的,还有Regex.Replace(String,String,Int32),它可以执行相同的操作,但是在运行时可能会更昂贵,因为它利用了功能齐全的解析器,其中我的方法可以找到一个字符串和三个字符串级联。

EDIT2:如果这是一项常见任务,则可能需要使该方法成为扩展方法:

public static class StringExtension
{
  public static string ReplaceFirst(this string text, string search, string replace)
  {
     // ...same as above...
  }
}

使用上面的示例,现在可以编写:

str = str.ReplaceFirst("brown", "quick");

在Csyntax中:

int loc = original.IndexOf(oldValue);
if( loc < 0 ) {
    return original;
}
return original.Remove(loc, oldValue.Length).Insert(loc, newValue);

扩展方法将执行此操作:

public static class StringExt
{
    public static string ReplaceFirstOccurrence(this string s, string oldValue, string newValue)
    {
         int i = s.IndexOf(oldValue);
         return s.Remove(i, oldValue.Length).Insert(i, newValue);    
    } 
}

享受

并且由于还考虑了VB.NET,因此我想提供以下内容:

Private Function ReplaceFirst(ByVal text As String, ByVal search As String, ByVal replace As String) As String
    Dim pos As Integer = text.IndexOf(search)
    If pos >= 0 Then
        Return text.Substring(0, pos) + replace + text.Substring(pos + search.Length)
    End If
    Return text 
End Function

正如itsmatt所说的,Regex.Replace是一个很好的选择,但是为了使他的答案更完整,我将用代码示例来填充它:

using System.Text.RegularExpressions;
...
Regex regex = new Regex("foo");
string result = regex.Replace("foo1 foo2 foo3 foo4", "bar", 1);             
// result = "bar1 foo2 foo3 foo4"

第三个参数(在这种情况下设置为1)是要从字符串的开头开始在输入字符串中替换的正则表达式模式的出现次数。

我希望可以使用静态Regex.Replace重载来完成此操作,但不幸的是,我们似乎需要Regex实例才能完成此操作。

using System.Text.RegularExpressions;

RegEx MyRegEx = new RegEx("F");
string result = MyRegex.Replace(InputString, "R", 1);

将在InputString中找到第一个F并将其替换为R。

考虑到"仅第一",也许:

int index = input.IndexOf("AA");
if (index >= 0) output = input.Substring(0, index) + "XQ" +
     input.Substring(index + 2);

或者更笼统地说:

public static string ReplaceFirstInstance(this string source,
    string find, string replace)
{
    int index = source.IndexOf(find);
    return index < 0 ? source : source.Substring(0, index) + replace +
         source.Substring(index + find.Length);
}

然后:

string output = input.ReplaceFirstInstance("AA", "XQ");

假设只有在字符串的开头,才需要替换" AA":

var newString;
if(myString.StartsWith("AA"))
{
  newString ="XQ" + myString.Substring(2);
}

如果我们需要替换第一次出现的" AA",无论字符串是否以它开头,请使用Marc的解决方案。

string abc = "AAAAX1";

            if(abc.IndexOf("AA") == 0)
            {
                abc.Remove(0, 2);
                abc = "XQ" + abc;
            }

Regex.Replace的重载之一将int表示为"可以发生替换的最大次数"。显然,使用Regex.Replace替换纯文本似乎有点过头,但是它确实很简洁:

string output = (new Regex("AA")).Replace(input, "XQ", 1);