tags:

views:

2971

answers:

6

Unless I am missing an obvious built in method what is the quickest way to get the nth occurrence of a string within a string.

I could loop the indexof method with the start index being updated on each loop but it sounds wasteful to me.

+10  A: 

That's basically what you need to do - or at least, it's the easiest solution. All you'd be "wasting" is the cost of n method invocations - you won't actually be checking any case twice, if you think about it. (IndexOf will return as soon as it finds the match, and you'll keep going from where it left off.)

Jon Skeet
I suppose your right, it does seem like there should be a built in method though, i'm sure it's a commmon occurrence.
PeteT
Really? I can't remember ever having to do it in about 13 years of Java and C# development. That doesn't mean I've really never had to do it - but just not often enough to remember.
Jon Skeet
+1  A: 

I would use a regular expressions for that then you have to optimal way of matching the string within the string.

This in one of the beautiful DSLs we all should use when possible.

An example in VB.net the code is almost the same in C#.

bovium
I would place good money on the regular expressions version being significantly harder to get right than "keep looping and doing simple String.IndexOf". Regular expressions have their place, but shouldn't be used when simpler alternatives exist.
Jon Skeet
+8  A: 

You really could use the regular expression /((s).*?){n}/ to search for n-th occurrence of substring s.

In C# it might look like this:

public static class StringExtender
{
    public static int NthIndexOf(this string target, string value, int n)
    {
        Match m = Regex.Match(target, "((" + value + ").*?){" + n + "}");

        if (m.Success)
            return m.Groups[2].Captures[n - 1].Index;
        else
            return -1;
    }
}
Alexander Prokofyev
I just successfully used this regex snipit - thanks for posting!
Adam McKee
Actually, this should be the accepted answer!!
Yogesh
A: 

Alexander -

Your solution worked great. It will save me much work. Many thanks.

Tim S.

A: 
private int IndexOfOccurence(string s, string match, int occurence)
{
    int i = 1;
    int index = 0;

    while (i <= occurence && (index = s.IndexOf(match, index + 1)) != -1)
    {
        if (i == occurence)
            return index;

        i++;
    }

    return -1;
}

or in C# with extension methods

public static int IndexOfOccurence(this string s, string match, int occurence)
{
    int i = 1;
    int index = 0;

    while (i <= occurence && (index = s.IndexOf(match, index + 1)) != -1)
    {
        if (i == occurence)
            return index;

        i++;
    }

    return -1;
}
Schotime
A: 

"int index = -1 ;" shoul be instead of "int index = 0 ; " in order to find the true value...

alper