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.)
Hier ist die rekursive Implementierung (der oben Idee) als Erweiterungsmethode, um das Format des Rahmenverfahren nachahmt (s):
public static int IndexOfNth(this string input,
string value, int startIndex, int nth)
{
if (nth < 1)
throw new NotSupportedException("Param 'nth' must be greater than 0!");
if (nth == 1)
return input.IndexOf(value, startIndex);
var idx = input.IndexOf(value, startIndex);
if (idx == -1)
return -1;
return input.IndexOfNth(value, idx + 1, --nth);
}
Auch hier sind einige (MBUnit) Unit Tests, die migh t Hilfe, die Sie (um es zu beweisen ist richtig):
using System;
using MbUnit.Framework;
namespace IndexOfNthTest
{
[TestFixture]
public class Tests
{
//has 4 instances of the
private const string Input = "TestTest";
private const string Token = "Test";
/* Test for 0th index */
[Test]
public void TestZero()
{
Assert.Throws<NotSupportedException>(
() => Input.IndexOfNth(Token, 0, 0));
}
/* Test the two standard cases (1st and 2nd) */
[Test]
public void TestFirst()
{
Assert.AreEqual(0, Input.IndexOfNth("Test", 0, 1));
}
[Test]
public void TestSecond()
{
Assert.AreEqual(4, Input.IndexOfNth("Test", 0, 2));
}
/* Test the 'out of bounds' case */
[Test]
public void TestThird()
{
Assert.AreEqual(-1, Input.IndexOfNth("Test", 0, 3));
}
/* Test the offset case (in and out of bounds) */
[Test]
public void TestFirstWithOneOffset()
{
Assert.AreEqual(4, Input.IndexOfNth("Test", 4, 1));
}
[Test]
public void TestFirstWithTwoOffsets()
{
Assert.AreEqual(-1, Input.IndexOfNth("Test", 8, 1));
}
}
}
Ähnlich: http://StackOverflow.com/A/9908392/1305911 – JNF
Ich würde einen regulären Ausdrücke dafür verwenden, dann müssen Sie optimal Möglichkeit, die Zeichenfolge innerhalb der Zeichenfolge abzugleichen. Dies in einem der schönen DSLs, die wir alle benutzen sollten, wenn es möglich ist. [Ein Beispiel] (http://www.regular-expressions.info/dotnet.html "Link") in VB.net ist der Code in C# fast identisch. – bovium
Ich würde gutes Geld auf die Version mit regulären Ausdrücken setzen, die wesentlich schwieriger ist, richtig zu machen als "keep looping and doing simple String.IndexOf". Reguläre Ausdrücke haben ihren Platz, sollten aber nicht verwendet werden, wenn einfachere Alternativen existieren. –