8

I have a string which may contain "title1" twice in it.

e.g.

server/api/shows?title1=its always sunny in philadelphia&title1=breaking bad ...

I need to change the second instance of the word "title1" to "title2"

I already know how to identify whether there ARE two instances of the string in the string.

int occCount = Regex.Matches(callingURL, "title1=").Count;

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

I know we can probably use Regex here but I'm not able to get the replace on the second instance. Can anyone give me a hand?

JJ.
  • 9,580
  • 37
  • 116
  • 189

6 Answers6

15

This will only replace the second instance of title1 (and any subsequent instances) after the first:

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

However, if there are more than 2 instances, it may not be what you want. It's a little crude, but you can do this to handle any number of occurrences:

int i = 1;
string output = Regex.Replace(input, @"title1", m => "title" + i++);
p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
  • pswg, I know I already accepted your answer but I just tried to do exactly the same thing but with the word "episodetitle1" and it's not giving me the same results. Care to give another hand? callingURL = Regex.Replace(callingURL, @"(?<=episodetitle1.*)episodetitle1", "episodetitle2"); – JJ. Jun 26 '13 at 17:05
  • @Rj. What's the input string? – p.s.w.g Jun 26 '13 at 17:10
  • something like this: server/api/Shows?title1=breaking%20bad&title2=two%20and%20a%20half%20men&episodetitle1=pilot&episodetitle2=a%20big%20bag%20of%20dog – JJ. Jun 26 '13 at 17:35
  • @Rj. Well it looks like that string has already had the second `episodetitle1` replaced with `episodetitle2`, but in any case, the pattern works for me whether you use `title1` or `episodetitle1`. – p.s.w.g Jun 26 '13 at 17:43
3

You can use the regex replace MatchEvaluator and give it a "state":

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

The replace can be one-lined by using the postfixed ++ operator (quite unreadable).

string callingUrl2 = Regex.Replace(callingURL, "title1=", x => found++ == 1 ? "title2=" : x.Value);
xanatos
  • 109,618
  • 12
  • 197
  • 280
2

you can specify a count, and an index to start searching at

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);
  • This is a good approach, but why would you use a regular expression in the last step? You could simply do a `string.Replace`. – p.s.w.g Jun 26 '13 at 17:22
  • @p.s.w.g does `string.Replace` have a field specifying where you start the search? – Sam I am says Reinstate Monica Jun 26 '13 at 17:25
  • Nope, you're right. You'd have to do a couple of `string.Substring`'s first (like a one answer had, which is now deleted). – p.s.w.g Jun 26 '13 at 17:29
  • Just what I needed - couldn't find this in static API. I'm disappointed that the static method of same name is missing this basic feature; it tricked me into believing that the API lacked it. IMHO great example of how you shouldn't overload method names if you're going to re-implement the static / non-static method with different feature sets. – Adam Jul 18 '15 at 22:34
1

You could perhaps make use of a negative lookahead:

title1(?!.*title1)

And replace with title2.

See how it's working here.

Jerry
  • 70,495
  • 13
  • 100
  • 144
0

I found this link immediately on a google search.

C# - indexOf the nth occurrence of a string?

Get the IndexOf the first occurrence of the string.

Use the returned IndexOf's startIndex +1 for the starting position of the second IndexOf.

Substring it into two strings at the appropriate index of the "1" character.

Concat it back together with the "2" character.

Community
  • 1
  • 1
deegee
  • 1,553
  • 14
  • 13
0

The way P.S.W.G did is really awesome. but below I mentioned one simple way to get it done for those who do have problem in lambda and regex expression..;)

int index = input.LastIndexOf("title1=");

string output4 = input.Substring(0, index - 1) + "&title2" + input.Substring(index + "title1".Length, input.Length - index - "title1".Length);

Ankur Bhutani
  • 3,079
  • 4
  • 29
  • 26