我知道我可以调用 ToString().IndexOf(...),但我不想创建额外的字符串。我知道我可以手动编写搜索例程。我只是想知道为什么框架中还没有这样的例程。
问问题
18093 次
4 回答
53
我知道这是一个老问题,但是我编写了一个扩展方法,它IndexOf
在StringBuilder
. 它在下面。我希望它可以帮助任何通过Google搜索或搜索StackOverflow找到这个问题的人。
/// <summary>
/// Returns the index of the start of the contents in a StringBuilder
/// </summary>
/// <param name="value">The string to find</param>
/// <param name="startIndex">The starting index.</param>
/// <param name="ignoreCase">if set to <c>true</c> it will ignore case</param>
/// <returns></returns>
public static int IndexOf(this StringBuilder sb, string value, int startIndex, bool ignoreCase)
{
int index;
int length = value.Length;
int maxSearchLength = (sb.Length - length) + 1;
if (ignoreCase)
{
for (int i = startIndex; i < maxSearchLength; ++i)
{
if (Char.ToLower(sb[i]) == Char.ToLower(value[0]))
{
index = 1;
while ((index < length) && (Char.ToLower(sb[i + index]) == Char.ToLower(value[index])))
++index;
if (index == length)
return i;
}
}
return -1;
}
for (int i = startIndex; i < maxSearchLength; ++i)
{
if (sb[i] == value[0])
{
index = 1;
while ((index < length) && (sb[i + index] == value[index]))
++index;
if (index == length)
return i;
}
}
return -1;
}
于 2011-07-06T18:29:31.620 回答
7
不幸的是,为 String 实现的许多方法可以为 StringBuilder 实现,但没有这样做。考虑使用扩展方法来添加您关心的内容。
于 2009-08-31T23:57:33.333 回答
0
丹尼斯,很好的解决方案。谢谢。我建议稍微优化一下:
public static int IndexOf(
this StringBuilder sb,
string value,
int startIndex,
bool ignoreCase)
{
int len = value.Length;
int max = (sb.Length - len) + 1;
var v1 = (ignoreCase)
? value.ToLower() : value;
var func1 = (ignoreCase)
? new Func<char, char, bool>((x, y) => char.ToLower(x) == y)
: new Func<char, char, bool>((x, y) => x == y);
for (int i1 = startIndex; i1 < max; ++i1)
if (func1(sb[i1], v1[0]))
{
int i2 = 1;
while ((i2 < len) && func1(sb[i1 + i2], v1[i2]))
++i2;
if (i2 == len)
return i1;
}
return -1;
}
于 2020-11-27T16:02:04.513 回答
-1
令人困惑的是,调用ToString()
aStringBuilder
不会创建额外的对象。在内部,StringBuilder
存储一个 String 对象,用于性能;调用ToString()
只是返回该对象。
于 2009-09-01T00:01:44.527 回答