Ale*_* Dn 13 .net c# string stringbuilder
检查是否StringBuilder以特定字符串结束的最佳(最短和最快)方法是什么?
如果我只想检查一个字符,这不是问题sb[sb.Length-1] == 'c',但如何检查它是否以更长的字符串结尾?
我可以考虑像循环"some string".Length和逐个读取字符之类的东西,但也许存在更简单的东西?:)
最后我想要像这样的扩展方法:
StringBuilder sb = new StringBuilder("Hello world");
bool hasString = sb.EndsWith("world");
Run Code Online (Sandbox Code Playgroud)
Dou*_*las 24
要避免生成完整字符串的性能开销,可以使用ToString(int,int)占用索引范围的重载.
public static bool EndsWith(this StringBuilder sb, string test)
{
if (sb.Length < test.Length)
return false;
string end = sb.ToString(sb.Length - test.Length, test.Length);
return end.Equals(test);
}
Run Code Online (Sandbox Code Playgroud)
编辑:可能需要定义一个带StringComparison参数的重载:
public static bool EndsWith(this StringBuilder sb, string test)
{
return EndsWith(sb, test, StringComparison.CurrentCulture);
}
public static bool EndsWith(this StringBuilder sb, string test,
StringComparison comparison)
{
if (sb.Length < test.Length)
return false;
string end = sb.ToString(sb.Length - test.Length, test.Length);
return end.Equals(test, comparison);
}
Run Code Online (Sandbox Code Playgroud)
编辑2:正如Tim S在评论中指出的那样,我的答案中存在一个缺陷(以及所有其他假设基于字符的相等的答案),这些缺陷会影响某些Unicode比较.Unicode不要求两个(子)字符串具有相同的字符序列.例如,预先组合的字符é应被视为等于e组合标记后面的字符U+0301.
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
string s = "We met at the cafe\u0301";
Console.WriteLine(s.EndsWith("café")); // True
StringBuilder sb = new StringBuilder(s);
Console.WriteLine(sb.EndsWith("café")); // False
Run Code Online (Sandbox Code Playgroud)
如果要正确处理这些情况,最简单的方法是调用StringBuilder.ToString(),然后使用内置函数String.EndsWith.
在 msdn 上,您可以找到有关如何在 StringBuilder 对象中搜索文本的主题。您可以使用的两个选项是:
因为第一个选项是不可能的。您必须使用 Chars 属性。
public static class StringBuilderExtensions
{
public static bool EndsWith(this StringBuilder sb, string text)
{
if (sb.Length < text.Length)
return false;
var sbLength = sb.Length;
var textLength = text.Length;
for (int i = 1; i <= textLength; i++)
{
if (text[textLength - i] != sb[sbLength - i])
return false;
}
return true;
}
}
Run Code Online (Sandbox Code Playgroud)