IndexOf 该类型的第 n 个字符

IndexOf n-th character of that type

我需要获取字符串中该类型的第 n 个字符的索引。

示例:

string test = "asdfasdfasdf";
int index = test.IndexOf("a", 3);

index 将是 8,因为第 3 个 a 的索引为 8

是否有一个函数可以做到这一点,或者您知道如何巧妙地做到这一点吗?

一个简单的 for 循环就可以解决问题,但是您可以将 for 循环放在 扩展方法 中,以便在整个应用程序中作为单行程序获得此功能。

像这样:

public static int NthIndexOf(this string text, char letter, int occurrence)
{
    if (text == null) throw new ArgumentNullException(nameof(text));

    int count = 0;
    for (int index = 0; index < text.Length; index++)
        if (text[index] == letter)
        {
            if (++count == occurrence)
                return index;
        }
    return -1;
}

用法:

string test = "asdfasdfasdf";
int index = test.IndexOf('a', 3);  

你可以在一行中完成,但它并不漂亮:

var s = "aabbabhjhjdsfbaxt";
var idx = s.Select((c, i) => new {c, i})
    .Where(p => p.c == 'a')
    .Skip(2)
    .FirstOrDefault()?.i ?? -1;

思路是将字符与其索引配对,按字符过滤,跳过n-1项,如果存在则取下一个。

另一种方法是使用带后视的正则表达式:

var idx = Regex.Match(s, "(?<=(a[^a]*){2})a").Index;

这匹配前面有两个 'a''a',中间可能还有其他字符。

您可以像这样创建一个扩展方法:

public static int NthIndexOf(this string s, char c, int occurence)
{
    if (s == null) throw new ArgumentNullException(nameof(s));
    if (occurence <= 0) return -1;

    int i = -1, o = 0;
    do
    {
        i = s.IndexOf(c, i+1);
        o++;
    } while (i >= 0 && o < occurence);

    return i;
}

检查输入参数后,它连续使用 string.IndexOf() 获取所需字符的第 n 个索引 c
如果没有进一步出现 c (IndexOf returns -1),则循环中断。


用法:

string test = "asdfasdfasdf";
int index = test.NthIndexOf('a', 3); // 8

当然,您可以对 c 而不是 charstring 类型的参数执行相同的操作,但需要将 s.IndexOf(c, i+1) 更改为 s.IndexOf(c, i+c.Length).

正如 René Vogt 所说,出于性能原因,您应该使用扩展方法链接对 IndexOf() 的调用:

public static int NthIndexOf(this string s, string value, int n)
{
    var index = -1;

    for (; n > 0; n--)
        index = s.IndexOf(value, index + 1);

    return index;
}

此 returns 字符串 value.

的(从 1 开始)n 次出现的从 0 开始的索引

这是一个工作示例:https://dotnetfiddle.net/xlqf2B