是否有一个命令可以获取字符串中字符的第三个索引?例如:
error: file.ext: line 10: invalid command [test:)]
在上面的句子中,我想要第3个冒号的索引,10个旁边的那个。我怎么能这样做?我知道string.IndexOf和string.LastIndexOf,但在这种情况下我想得到第三次使用时字符的索引。
答案 0 :(得分:13)
String.IndexOf
会得到第一个索引,但是有重载给出起点。因此,您可以使用第一个IndexOf
加1的结果作为下一个的起点。然后只是累积索引足够多次:
var offset = myString.IndexOf(':');
offset = myString.IndexOf(':', offset+1);
var result = myString.IndexOf(':', offset+1);
添加错误处理,除非您知道myString
包含至少三个冒号。
答案 1 :(得分:9)
你可以这样写:
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);
答案 2 :(得分:4)
我猜你想把那个字符串解析成不同的部分。
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 (: ]"
}
答案 3 :(得分:2)
已经有几种非常好的方法可以解决这个问题 - 但我决定尝试使用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();
}
并进行测试以证明这一点:
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));
答案 4 :(得分:0)
您可以调用.IndexOf(char,position)从所需位置进行搜索,因此您应该调用它3次(但是,在每次调用之后,您还应该检查是否找到了某些内容)。
答案 5 :(得分:0)
int pos = -1;
for ( int k = 0; k < 3; ++k )
{
pos = s.indexOf( ':', pos+1 );
// Check if pos < 0...
}
答案 6 :(得分: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;
}
答案 7 :(得分:0)
这是一个递归实现(对于字符串而不是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)单元测试可以帮助你(证明它是正确的):
[Test]
public void TestIndexOfNthWorksForNth1()
{
const string input = "foo<br />bar<br />baz<br />";
Assert.AreEqual(3, input.IndexOfNth("<br />", 0, 1));
}
[Test]
public void TestIndexOfNthWorksForNth2()
{
const string input = "foo<br />whatthedeuce<br />kthxbai<br />";
Assert.AreEqual(21, input.IndexOfNth("<br />", 0, 2));
}
[Test]
public void TestIndexOfNthWorksForNth3()
{
const string input = "foo<br />whatthedeuce<br />kthxbai<br />";
Assert.AreEqual(34, input.IndexOfNth("<br />", 0, 3));
}
答案 8 :(得分:0)
请在类似问题上查看此答案:
https://stackoverflow.com/a/46460083/7673306
它提供了一种方法,用于查找指定字符串中特定字符第n次出现的索引。
在您的具体情况下,它将如下实施:
int index = IndexOfNthCharacter("error: file.ext: line 10: invalid command [test:)]", 3, ':');
答案 9 :(得分:0)
简单地用char分割字符串。 这为您提供了一个数组,您可以将其用于定位所需的内容。
var stringToSplit = "one_two_three_four";
var splitString = stringToSplit.Split("_");
if (splitString.length > 3){
var newString = $"{splitResult[0]}_{splitResult[1]}_{splitResult[2]}";
}