.NET StringBuilder-проверить, заканчивается ли строка

что лучше (короткий и быстрый) способ проверить, если StringBuilder заканчивается определенной строкой?

если я хочу проверить только один символ, это не проблема sb[sb.Length-1] == 'c', но как проверить, заканчивается ли она более длинной строкой?

Я могу думать о чем-то вроде зацикливания от "some string".Length и читать символы один за другим, но, может быть, существует что-то более простое? :)

В конце я хочу иметь метод расширения такой:

StringBuilder sb = new StringBuilder("Hello world");
bool hasString = sb.EndsWith("world");

4 ответов


чтобы избежать накладных расходов на создание полной строки, вы можете использовать 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);
}

редактировать: наверное, было бы желательно определить перегрузку, которая принимает :

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);
}

редактировать2: как указал Тим S в комментариях, в моем ответе есть недостаток (и все другие ответы, которые предполагают равенство на основе символов) это влияет на некоторые сравнения Unicode. Unicode не требует, чтобы две (sub)строки имели одинаковую последовательность символов, которые считаются равными. Например, предварительно составленный символ é следует рассматривать как равный символ 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

если вы хотите правильно обрабатывать эти случаи, это может быть проще просто позвонить StringBuilder.ToString(), а затем использовать встроенный String.EndsWith.


на msdn вы можете найти тему на Как искать текст в объекте StringBuilder. Доступны два варианта:

  1. вызовите ToString и выполните поиск возвращаемого объекта String.
  2. используйте свойство 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;
    }
}

TL; DR

если вы цель состоит в том, чтобы получить кусок или весь StringBuilderсодержание в


Я даю вам то, что вы просили (с ограничениями, которые вы указываете), но не лучший способ сделать это. Что-то вроде:

StringBuilder sb = новый StringBuilder ("Привет миру"); bool hasString = sb.Снять(1, sb.Длина - "мир".Длина) == "мир";