C#字符串中字符的第三个索引

是否有一个命令可以获取字符串中字符的第三个索引? 例如:

error: file.ext: line 10: invalid command [test:)] 

在上面的句子中,我想要第3个冒号的索引,10个旁边的那个。我怎么能这样做? 我知道string.IndexOf和string.LastIndexOf,但在这种情况下我想得到第三次使用时字符的索引。

String.IndexOf会得到第一个索引,但是有重载给出一个起点。 因此,您可以使用第一个IndexOf加1的结果作为下一个的起点。 然后只需累积索引足够次数:

 var offset = myString.IndexOf(':'); offset = myString.IndexOf(':', offset+1); var result = myString.IndexOf(':', offset+1); 

除非您知道myString包含至少三个冒号,否则添加error handling。

你可以这样写:

  public static int CustomIndexOf(this string source, char toFind, int position) { int index = -1; for (int i = 0; i < position; i++) { index = source.IndexOf(toFind, index + 1); if (index == -1) break; } return index; } 

编辑 :显然你必须按如下方式使用它:

 int colonPosition = myString.CustomIndexOf(',', 3); 

我猜你想把那个字符串解析成不同的部分。

 public static void Main() { var input = @"error: file.ext: line 10: invalid command [test (: ]"; var splitted = input .Split(separator: new[] {": "}, count: 4, options: StringSplitOptions.None); var severity = splitted[0]; // "error" var filename = splitted[1]; // "file.ext" var line = splitted[2]; // "line 10" var message = splitted[3]; // "invalid command [test (: ]" } 

这已经得到了几个很好的解决方法 – 但我决定尝试使用Expressions来编写它。

 private int? GetNthOccurrance(string inputString, char charToFind, int occurranceToFind) { int totalOccurrances = inputString.ToCharArray().Count(c => c == charToFind); if (totalOccurrances < occurranceToFind || occurranceToFind <= 0) { return null; } var charIndex = Enumerable.Range(0, inputString.Length - 1) .Select(r => new { Position = r, Char = inputString[r], Count = 1 }) .Where(r => r.Char == charToFind); return charIndex .Select(c => new { c.Position, c.Char, Count = charIndex.Count(c2 => c2.Position <= c.Position) }) .Where(r => r.Count == occurranceToFind) .Select(r => r.Position) .First(); } 

和测试来certificate它:

 Assert.AreEqual(0, GetNthOccurrance(input, 'h', 1)); Assert.AreEqual(3, GetNthOccurrance(input, 'l', 2)); Assert.IsNull(GetNthOccurrance(input, 'z', 1)); Assert.IsNull(GetNthOccurrance(input, 'h', 10)); 

您可以调用.IndexOf(char,position)从所需位置进行搜索,因此您应该调用它3次(但是,在每次调用之后,您还应该检查是否找到了某些内容)。

 int pos = -1; for ( int k = 0; k < 3; ++k ) { pos = s.indexOf( ':', pos+1 ); // Check if pos < 0... } 

有点丑陋,但另一种方法(对已经发布的其他方法)有效:

 public int FindThirdColonIndex(string msg) { for (int i = 0, colonCount = 0; i < msg.Length; i++) { if (msg[i] == ':' && ++colonCount == 3) { return i; } } // Not found return -1; } 

这是一个递归实现(对于字符串而不是char) – 作为扩展方法,模仿框架方法的格式。

您需要做的就是在扩展方法中将’字符串值’更改为’char value’并相应地更新测试并且它将起作用…我很乐意这样做并发布它,如果有人有兴趣吗?

 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) input.IndexOf(value, startIndex); return input.IndexOfNth(value, input.IndexOf(value, startIndex) + 1, --nth); } 

此外,这里有一些(MBUnit)unit testing可能会帮助你(certificate它是正确的):

 [Test] public void TestIndexOfNthWorksForNth1() { const string input = "foo
bar
baz
"; Assert.AreEqual(3, input.IndexOfNth("
", 0, 1)); } [Test] public void TestIndexOfNthWorksForNth2() { const string input = "foo
whatthedeuce
kthxbai
"; Assert.AreEqual(21, input.IndexOfNth("
", 0, 2)); } [Test] public void TestIndexOfNthWorksForNth3() { const string input = "foo
whatthedeuce
kthxbai
"; Assert.AreEqual(34, input.IndexOfNth("
", 0, 3)); }

请在类似问题上查看此答案: https : //stackoverflow.com/a/46460083/7673306
它提供了一种方法,用于查找指定字符串中特定字符第n次出现的索引。

在您的具体情况下,它将实现如下:

 int index = IndexOfNthCharacter("error: file.ext: line 10: invalid command [test:)]", 3, ':');