如何在.NET 中替换字符串的 * first instance * ?

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

我如何在.NET 中实现这一点?

75646 次浏览
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");

EDIT: As @itsmatt 提到, there's also Regex.Replace(String, String, Int32), which can do the same, but is probably more expensive at runtime, since it's utilizing a full featured parser where my method does one find and three string concatenations.

EDIT2 : 如果这是一个常见的任务,您可能希望将该方法作为扩展方法:

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

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

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

In C# syntax:

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

C # 扩展方法:

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

正如 它是无关紧要的所说,正则表达式,替换是一个很好的选择,然而,为了使他的答案更完整,我将填写一个代码样本:

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 实例来完成它。

using System.Text.RegularExpressions;


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

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

Taking the "first only" into account, perhaps:

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

这个示例将子字符串抽象出来(但速度较慢) ,但可能比正则表达式快得多:

var parts = contents.ToString().Split(new string[] { "needle" }, 2, StringSplitOptions.None);
return parts[0] + "replacement" + parts[1];

对于那些不介意提到 Microsoft.VisualBasic的人来说,有一款 Replace方法:

string result = Microsoft.VisualBasic.Strings.Replace("111", "1", "0", 2, 1); // "101"

使用 Span更新扩展方法以最小化新字符串创建

    public static string ReplaceFirstOccurrence(this string source, string search, string replace) {
int index = source.IndexOf(search);
if (index < 0) return source;
var sourceSpan = source.AsSpan();
return string.Concat(sourceSpan.Slice(0, index), replace, sourceSpan.Slice(index + search.Length));
}

使用 range 和 C # 10,我们可以做到:

public static string ReplaceFirst(this string text, string search, string replace)
{
int pos = text.IndexOf(search, StringComparison.Ordinal);
return pos < 0 ? text : string.Concat(text[..pos], replace, text.AsSpan(pos + search.Length));
}