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;
}
我找到了一个很好的扩展方法,可以在某些 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;
}