c#中如何用动态值替换字符串

本文关键字:替换 字符串 动态 何用 | 更新日期: 2023-09-27 18:07:44

我有这样的代码:

string a = "**MustbeReplaced**asdgasfsff**MustbeReplaced**asdfafasfsa";
//MustbeReplaced should be Replaced1, Replaced2, and so on
a = a.Replace("MustbeReplaced", "Replaced"); 

每次有一个字符串替换,我想用一个动态值替换它。例如,上面字符串的输出应该是:

"**Replaced1**asdgasfsff**Replaced2**asdfafasfsa"

我知道String。替换,但据我所知,它只用于静态String替换。

有什么办法可以做到吗?

c#中如何用动态值替换字符串

您可以使用Regex类并提供一个将为每次匹配调用一次的委托。它需要返回字符串,将匹配的文本替换为。

你只需要声明一个保存计数器的变量:

string a = "**MustbeReplaced**asdgasfsff**MustbeReplaced**asdfafasfsa";
int replacementIndex = 0;
string b = Regex.Replace(a, "MustbeReplaced", match =>
{
    replacementIndex++;
    return $"Replaced{replacementIndex}";
});

运行此命令后,b将包含以下内容:

**Replaced1**asdgasfsff**Replaced2**asdfafasfsa

注意:由于您现在使用的是Regex类,因此要注意Regex将使用的所有特殊字符,这些字符将使模式从简单的逐字符匹配扩展到逐字符匹配。如果要替换包含星号、问号、括号等符号的文本,则需要转义。

幸运的是,我们可以简单地要求Regex类为我们做:

string a = "**Mustbe?Replaced**asdgasfsff**Mustbe?Replaced**asdfafasfsa";
int replacementIndex = 0;
string b = Regex.Replace(a, Regex.Escape("Mustbe?Replaced"), match =>
{
    replacementIndex++;
    return $"Replaced{replacementIndex}";
});

使用Regex.Replace(String, MatchEvaluator)过载。相应的MSDN页面包含一个几乎完全符合您要求的示例。

这里有一个更简单的例子:

var input = "MustBeReplaced A MustBeReplaced B";
int i = 1;
MatchEvaluator evaluator = (m) => "Replaced " + (i++);
// yields Replaced 1 A Replaced 2 B
var result = Regex.Replace(input, "MustBeReplaced", evaluator);

您可以使用前面所示的正则表达式,也可以使用这种更有效但可读性较差的纯字符串方法:

string a = "**MustbeReplaced**asdgasfsff**MustbeReplaced**asdfafasfsa";
int matchCount = 0, index = 0;
while ((index = a.IndexOf("MustbeReplaced", index, StringComparison.Ordinal)) >= 0)
{
    a = a.Remove(index, "MustbeReplaced".Length).Insert(index, "Replaced" + ++matchCount);
}

可以这样做:

        string source = "**MustbeReplaced**asdgasfsff**MustbeReplaced**asdfafasfsa";
        int count = 0;
        var result = Regex.Replace(source, "MustbeReplaced", m => "Replaced" + (++count));

想要避免使用正则表达式吗?想要更多的性能?使用这个代码。这段代码一次只使用了一个StringBuilder。

    public static string ReplaceWithNumberPrefix(this string source, string oldString, string newString, int numberPrefixStart)
    {
        var oldStringLength = oldString.Length;
        var indexes = new List<int>();
        var p = source.IndexOf(oldString);                    
        if (p >= 0)
            do
            {
                indexes.Add(p);
                p = source.IndexOf(oldString, p + 1);                    
            } while (p >= 0);
        var builder = new System.Text.StringBuilder(source);
        var trailingDifference = 0;
        for (int i = 0; i < indexes.Count; i++)
        {
            var replacement = string.Concat(newString, numberPrefixStart);
            var startIndex = indexes[i] + trailingDifference;
            builder.Replace(oldString, replacement, startIndex, oldStringLength);
            numberPrefixStart++;
            trailingDifference = trailingDifference + replacement.Length - oldStringLength;
        }
        return builder.ToString();
    }