C# string.IndexOfNthFromEnd() 扩展方法

C# string.IndexOfNthFromEnd() extension method

我找到了一个很好的扩展方法,可以在某些 input 字符串中找到第 N 次出现的 value

public static int IndexOfNth(this string input, string value, int startIndex, int nth)
{
    if (nth < 1)
        throw new ArgumentException("Can not find the zeroth index of substring in string. Must start with 1");
    if (nth == 1)
        return input.IndexOf(value, startIndex, StringComparison.Ordinal);
    var idx = input.IndexOf(value, startIndex, StringComparison.Ordinal);
    if (idx == -1)
        return -1;
    return input.IndexOfNth(value, idx + value.Length, --nth);
}

我需要下一个,但不能自己改造:

IndexOfNthFromEnd(this string input, string value, int nth)

它应该找到从字符串末尾开始第 N 次出现的索引。例如:

IndexOfNthFromEnd("-!-!----", "!", 2) // = 1;
IndexOfNthFromEnd("-!-!----", "!", 1) // = 3;
IndexOfNthFromEnd("-!-!----", "-!", 2) // = 0;
IndexOfNthFromEnd("-!-!----", "-!", 1) // = 2;

也许不是最优雅的解决方案,但您可以使用以下方法反转输入字符串:

    char[] charArray = s.ToCharArray();
    Array.Reverse( charArray );
    (new string( charArray )).IndexOfNth("-!-!----", "!", 2);

并使用相同的扩展方法。

public static int IndexOfNthFromEnd(this string input, string value, int startIndex, int nth)
{
    if (nth < 1)
        throw new ArgumentException("Can not find the zeroth index of substring in string. Must start with 1");
    var idx = input.LastIndexOf(value, startIndex, StringComparison.Ordinal);
    if (idx == -1 || nth == 1)
        return idx;
    return input.IndexOfNthFromEnd(value, idx - value.Length, --nth);
}

请注意,您原来的 IndexOfNth 确实应该这样做:

return input.IndexOfNth(value, idx + value.Length, --nth);

otherwise for: "abababa".IndexOfNth("bab", 0, 2) it returns 3、当它应该是-1 因为bab只在字符串中出现一次

这是一种迭代方法,可以保留问题中概述的签名(即,没有起始索引参数)。如果您的字符串包含大量重复,这可能不是最有效的方法,但它确实有效。我也没有从原始例程中添加任何可爱的参数验证。

public static int IndexOfNthFromEnd(this string input, string value, int nth)
{
    var newString = input;
    var index = 0;

    while (nth-- > 0 && index >= 0)
    {
        index = newString.LastIndexOf(value);
        newString = newString.Substring(0, index);
    }

    return index;
}

试试看这个 example

private static int IndexOfNth(string str, char c, int n) {
    int s = -1;

    for (int i = 0; i < n; i++) {
        s = str.IndexOf(c, s + 1);

        if (s == -1) break;
    }

    return s;
}