Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET StringBuilder - check if ends with string

What is the best (shortest and fastest) way to check if StringBuilder ends with specific string?

If I want to check just one char, that's not a problem sb[sb.Length-1] == 'c', but how to check if it's ends with longer string?

I can think about something like looping from "some string".Length and read characters one by one, but maybe there exists something more simple? :)

At the end I want to have extension method like this:

StringBuilder sb = new StringBuilder("Hello world");
bool hasString = sb.EndsWith("world");
like image 497
Alex Dn Avatar asked Jul 10 '13 20:07

Alex Dn


People also ask

How do I know if my StringBuilder is empty?

Check if StringBuilder Is Empty Using the Length Property The StringBuilder class has a property named Length that shows how many Char objects it holds. If Length is zero that means the instance contains no characters.

How do you check if a StringBuilder contains a character?

StringBuilder doesn't have a contains() method, but it does have the indexOf() method. Therefore, you can check for the index of character and if it returns -1 , the character is not present in the StringBuilder .

Can we compare StringBuilder with String?

We can use the equals() method for comparing two strings in Java since the String class overrides the equals() method of the Object class, while StringBuilder doesn't override the equals() method of the Object class and hence equals() method cannot be used to compare two StringBuilder objects.

Does StringBuilder have trim method?

It doesn't have a trim() method because it is very easy and somewhat preferred to use immutable objects. Imagine one thread is trimming the StringBuilder while another is appending to it.


1 Answers

To avoid the performance overhead of generating the full string, you can use the ToString(int,int) overload that takes the index range.

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

Edit: It would probably be desirable to define an overload that takes a StringComparison argument:

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

Edit2: As pointed out by Tim S in the comments, there is a flaw in my answer (and all other answers that assume character-based equality) that affects certain Unicode comparisons. Unicode does not require two (sub)strings to have the same sequence of characters to be considered equal. For example, the precomposed character é should be treated as equal to the character e followed by the combining mark 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

If you want to handle these cases correctly, it might be easiest to just call StringBuilder.ToString(), and then use the built-in String.EndsWith.

like image 164
Douglas Avatar answered Oct 13 '22 01:10

Douglas