如何在字符串中替换特定的字符串出现次数?

8
我有一个字符串,其中可能包含两个"title1"。
例如:
server/api/shows?title1=its always sunny in philadelphia&title1=breaking bad ...
我需要将第二个"title1"更改为"title2"。
我已经知道如何确定字符串中是否有两个该字符串的实例。
int occCount = Regex.Matches(callingURL, "title1=").Count;

if (occCount > 1)
{
     //here's where I need to replace the second "title1" to "title2"
}

我知道我们可能可以在这里使用正则表达式,但我无法在第二个实例上进行替换。有人能帮帮我吗?


4
如果有三个title1单词实例,你需要将第三个更改为title3吗? - Sam I am says Reinstate Monica
这对我来说听起来像是一个更广泛的问题。 - Dan Teesdale
绝不超过2个实例。 - JJ.
1
你知道那句老话“永远不要说永远”。 - MethodMan
我有检查确保字符串永远不会超过两个实例。外部字符串是根据用户在屏幕上的选择构建的,并且我考虑了正确的选择... - JJ.
6个回答

15

这将仅替换第二个出现的 title1(以及在第一次后出现的任何实例):

string output = Regex.Replace(input, @"(?<=title1.*)title1", "title2");

然而,如果存在超过2个实例,它可能不是您想要的。这种处理方式有些粗糙,但您可以使用此方法来处理任意数量的出现次数:

int i = 1;
string output = Regex.Replace(input, @"title1", m => "title" + i++);

PSWG,我知道我已经接受了你的答案,但我刚刚尝试完全相同的操作,只是将单词“episodetitle1”替换为“episodetitle2”,但它没有给我相同的结果。能否再帮我一下?callingURL = Regex.Replace(callingURL, @"(?<=episodetitle1.*)episodetitle1", "episodetitle2"); - JJ.
@Rj。输入字符串是什么? - p.s.w.g
服务器/API/Shows?title1=破产姐妹和两个半男人&title2=风骚律师和生活大爆炸&episodetitle1=试播集&episodetitle2=一袋狗粮 - JJ.
@Rj。看起来这个字符串已经用episodetitle2替换了第二个episodetitle1,但无论如何,这个模式对我都有效,不管你使用title1还是episodetitle1 - p.s.w.g

3
您可以使用正则表达式替换 MatchEvaluator 并给它一个 "状态":
string callingURL = @"server/api/shows?title1=its always sunny in philadelphia&title1=breaking bad";

int found = -1;
string callingUrl2 = Regex.Replace(callingURL, "title1=", x =>
{
    found++;
    return found == 1 ? "title2=" : x.Value;
});

替换可以使用后缀 ++ 运算符一行完成(但很难读懂)。
string callingUrl2 = Regex.Replace(callingURL, "title1=", x => found++ == 1 ? "title2=" : x.Value);

2
您可以指定一个计数和一个开始搜索的索引。
string str = @"server/api/shows?title1=its always sunny in philadelphia&title1=breaking bad ...";

Regex regex = new Regex(@"title1");
str = regex.Replace(str, "title2", 1, str.IndexOf("title1") + 6);

这是一个不错的方法,但是为什么你在最后一步要使用正则表达式呢?你可以直接使用 string.Replace - p.s.w.g
@p.s.w.g, string.Replace 方法中是否有指定搜索起始位置的字段? - Sam I am says Reinstate Monica
不错,你是对的。你需要先使用一些 string.Substring(就像一个回答中提到的,但现在已被删除)。 - p.s.w.g
正是我需要的 - 在静态 API 中找不到。我很失望,同名的静态方法缺少这个基本功能;它让我误以为 API 缺少了它。在我看来,这是一个很好的例子,说明如果你要使用不同的特性集重新实现静态/非静态方法,就不应该重载方法名称。 - Adam

1
你可以尝试使用负向先行断言: ```

你可以尝试使用负向先行断言:

```
title1(?!.*title1)

将其替换为title2

这里查看其工作原理。


@Anirudh 用户已经通过 if 确保存在两个 title1 实例。 - Jerry
它可以只出现一次。 - Anirudha

0

我在谷歌搜索中立即找到了这个链接。

C# - indexOf字符串的第n次出现?

获取字符串的第一个出现的IndexOf。

使用返回的IndexOf的startIndex +1作为第二个IndexOf的起始位置。

在“1”字符的适当索引处将其子字符串分成两个字符串。

将其与“2”字符拼接在一起。


0
P.S.W.G的方法真的很棒。但是下面我提到了一种简单的方法,适用于那些在lambda和regex表达式方面有问题的人..;)
int index = input.LastIndexOf("title1="); string output4 = input.Substring(0, index - 1) + "&title2" + input.Substring(index + "title1".Length, input.Length - index - "title1".Length);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接