Ander wenke

Jy moet regtig kan die gewone uitdrukking /((s).*?){n}/ gebruik om te soek na n-de voorkoms van substring s.

In C # is dit dalk so lyk:

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

        if (m.Success)
            return m.Groups[2].Captures[n - 1].Index;
        else
            return -1;
    }
}

Nota:. Ek het Regex.Escape bygevoeg oorspronklike oplossing te laat soek karakters wat spesiale betekenis aan regex enjin het

  

Dit is basies wat jy hoef te doen - of ten minste, dis die maklikste oplossing. Al wat jy wil word "mors" is die koste van N metode aanroepingen - jy sal nie eintlik elk geval twee keer nagaan, as jy daaroor dink. (IndexOf sal so gou as dit die wedstryd vind om terug te keer, en jy sal aanhou gaan uit waar dit opgehou het.)

Hier is die rekursiewe implementering (van die bo idee ) as 'n uitbreiding metode, bootsen die formaat van die raamwerk metode (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);
}

Ook hier is 'n paar (MBUnit) eenheid toetse wat jou kan help (om dit te bewys is korrek):

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

of in C # met uitbreiding metodes

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

Miskien sal dit ook lekker om te werk met die String.Split() Metode en kyk of die versoek voorkoms is in die skikking, as jy nie die indeks moet wees, maar die waarde van die indeks

Na 'n paar benchmarking, dit lyk na die eenvoudigste en mees doeltreffende oplossing wees

public static int IndexOfNthSB(string input,
             char value, int startIndex, int nth)
        {
            if (nth < 1)
                throw new NotSupportedException("Param 'nth' must be greater than 0!");
            var nResult = 0;
            for (int i = startIndex; i < input.Length; i++)
            {
                if (input[i] == value)
                    nResult++;
                if (nResult == nth)
                    return i;
            }
            return -1;
        }

System.ValueTuple FTW:

var index = line.Select((x, i) => (x, i)).Where(x => x.Item1 == '"').ElementAt(5).Item2;

skryf van 'n funksie van wat huiswerk

Dit kan dit doen:

Console.WriteLine(str.IndexOf((@"\")+2)+1);
scroll top