该类型的第n个字符的索引

本文关键字:字符 索引 类型 | 更新日期: 2023-09-27 18:04:37

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

示例:

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

并且index将是8,因为第三个a具有8 的索引

有没有一个函数可以做到这一点,或者你知道如何以智能的方式做到这一步吗?

该类型的第n个字符的索引

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

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

这个想法是将字符与它们的索引配对,按字符过滤,跳过n-1个项目,如果存在,则取下一个。

另一种方法是使用带有look-behind的regex:

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

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

一个简单的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);  

您可以创建这样的扩展方法:

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()来获得所需字符c的第n个索引
如果没有发现c的进一步出现(IndexOf返回-1(,则循环中断。


用法:

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

当然,对于c而不是char,您可以使用类型为string的参数来执行同样的操作,但需要将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;
}

这返回字符串value的第15次出现的(从1开始(CCD_的从0开始的索引。

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