60

I want to:

  1. Check a variable and determine if the last 2 characters are "Id"
  2. If yes, remove them.

I can do it with this below, but then it will blow up if there is an "Id" substring other than the end. Is there a RemoveFromEnd() method that takes a number of characters argument?

 if (column.EndsWith("Id"))
 {
       //remove last 2 characters
       column = column.replace("Id", "");
 }

I see this solution, which does this:

column = System.Text.RegularExpressions.Regex.Replace(column, "Id$", "");

but it says it's pretty slow and I am going to be running this code inside a code block that I would like to be extremely fast so I wanted to see if a faster solution is available.

4
  • Just curious how "slow" the regexp is (an end-anchor w/o backtracking should be zippy-fast) ... although substring is likely more appropriate here. OTOH, with the regexp there is no explicit conditional/EndsWith.
    – user166390
    Commented Mar 12, 2011 at 18:46
  • The Regex should be faster in the general case. Did you try with precompiling it or storing it as a member to use it in your method? (to avoid the cost of creating the regex each time)
    – jdehaan
    Commented Mar 12, 2011 at 18:58
  • possible duplicate of trim string at the end of the string
    – nawfal
    Commented Jan 5, 2014 at 11:20
  • 1
    The snippet you put removes all "Id" from the string if it has it as suffix, it will return "MyWrong" if the input string is "MyIdWrongId"...
    – Roberto
    Commented Jul 18, 2017 at 16:13

7 Answers 7

100

String.Substring can do that:

column = column.Substring(0, column.Length - 2);

You can use it to roll your own RemoveFromEnd:

public static string RemoveFromEnd(this string s, string suffix)
{
    if (s.EndsWith(suffix))
    {
        return s.Substring(0, s.Length - suffix.Length);
    }

    return s;
}
7
  • I agree with this approach if you don't want to use a regular expression. But really, how could this be faster?
    – DOK
    Commented Mar 12, 2011 at 18:50
  • @DOK: faster than what? the regexp?
    – Jon
    Commented Mar 12, 2011 at 18:51
  • 1
    @DOK: the string manipulation methods in .NET are highly performant. For simple operations like this I often find them to be very much faster than regular expressions. Commented Mar 12, 2011 at 18:51
  • 8
    can be modified to one-liner return s.EndsWith(suffix) ? s.Substring(0, s.Length - suffix.Length) : s;
    – aggaton
    Commented Mar 11, 2013 at 21:07
  • 1
    Could be modified to single line methods using c#6 expression-bodied methods and c# 8 ranges: public static string RemoveFromEnd(string s, string suffix) => s.EndsWith(suffix) ? s[..^suffix.Length] : s; Commented Nov 7, 2022 at 14:00
17

An alternative to the SubString method is to use a Regex.Replace from System.Text.RegularExpressions:

using System.Text.RegularExpressions;
...
column = Regex.Replace(column, @"Id$", String.Empty);

This way enables you to avoid the test, but not sure if it is really a speed benefit :-). At least an alternative that might be useful in some cases where you need to check for more than one thing at a time.

The regex can be compiled and re-used to get some performance increase and used instead of the call to the static method and can be used like this:

// stored as a private member
private static Regex _checkId = new Regex(@"Id$", RegexOptions.Compiled);
...
// inside some method
column = _checkId.Replace(column, String.Empty);
1
  • 1
    Did you ever made a comparison between compiled regex and EndsWith-Substring? Commented Nov 20, 2015 at 9:59
6

Well, there can be a RemoveFromEnd() method if you write your own:

public static string RemoveFromEnd(this string str, string toRemove)
{
    if (str.EndsWith(toRemove))
        return str.Substring(0, str.Length - toRemove.Length);
    else
        return str;
}

You can just use it as follows:

column = column.RemoveFromEnd("Id");
4

Since you know the length of the part to remove, you can use Substring:

if (column.EndsWith("Id"))
{    
    column = column.Substring(0, column.Length - 2);
}
2
  • If the last two characters are not Id, this will remove them in error.
    – DOK
    Commented Mar 12, 2011 at 18:48
  • 1
    @DOK: this is intended to be inside the if block, of course (instead of the call to Replace in the OP. Will add if-block for clarity though. Commented Mar 12, 2011 at 18:49
1

Try this:

if (column.IndexOf("Id") == column.Length-2) {
    column = column.Substring(0, column.Length-2);
}
1

With the (relatively) new Range Syntax introduced in C# 8 you can simplify the RemoveEnd method even more:

public static string RemoveFromEnd(this string s, string suffix)
{
    if (s.EndsWith(suffix))
    {
        return s[..^suffix.Length];
    }

    return s;
}
0

Couple of notes to add to @Jon's answer:

Do you want to do this case insensitively?

if (column.ToLower().EndsWith("id")) { column = column.Remove(column.Length - 2); }

If ID is unique in the string and needs to always be removed...

 #No if check....
 column = column.Replace("Id", "");

If its case insensitive and only occurs once I would still use the first check.

1
  • -1; this fails the Turkey Test. It's probably still fine for most contexts (since most code never needs to run in a Turkish locale), but for some readers, this code will effectively be broken.
    – Mark Amery
    Commented Sep 11, 2017 at 22:27

Not the answer you're looking for? Browse other questions tagged or ask your own question.