How to get last lower case characters as a string from string in C#

Hakan
Hakan used Ask the Experts™
on
I have a string with like below structures and i'd like to show what i want to get at the end.

FRCABisch --> isch
FrCABisch --> isch
YTkumoty --> kumoty


Any help would be grateful.

Thank you.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2015
Distinguished Expert 2018

Commented:
This wil do:

string input = "FrCABisch";
string trail = String.Empty;

foreach (var character in input)
{
	string check = character.ToString();
	if (character.ToString().Equals(character.ToString().ToUpper()))
	{
		trail = string.Empty;
	}
	else
	{
		trail += character;
	}
}

Console.WriteLine(trail);

// trail -> isch

Open in new window

Eduard GherguArchitect - Coder - Mentor

Commented:
Hi,

What're the criteria for getting these specific substrings?

Commented:
I would just do a regular expression:
string lastLowercaseChars = String.Empty;
var re = new Regex("[a-z]+$");
var match = re.Match("FrCABisch");
if(match.Success)
{
  lastLowercaseChars = match.Value;
}

// lastLowercaseChars has your final result

Open in new window


Gustav's method should work, too, but is very inefficient (building and truncating strings multiple times, many character to string conversions). It could be improved greatly by making one pass through the string in reverse order to find the last position of an uppercase character and then do a substring based on that result. The pseudo-code:

int posLastUpper = 0:
for(int i = input.Length - 1; i >= 0; i--)
{
  char c = input[i];
  if(c.IsUpper())
  {
    posLastUpper = i;
    break;
  }
}
string lastLowercaseChars = input.Substring(posLastUpper);

Open in new window


Might require some tweaking (e.g. if posLastUpper is 0 then just return the original string) but that idea should work a little more efficiently.
Rowby Goren Makes an Impact on Screen and Online

Learn about longtime user Rowby Goren and his great contributions to the site. We explore his method for posing questions that are likely to yield a solution, and take a look at how his career transformed from a Hollywood writer to a website entrepreneur.

Eduard GherguArchitect - Coder - Mentor

Commented:
Hi,
Sorry, I was not paying attention to the question title.
RegEx is the easiest way, indeed. Some sample code:
List<string> list = new List<string>();
   list.Add("FRCABisch");
   list.Add("FrCABisch");
   list.Add("YTkumoty");

   string pattern = @"([a-z][^A-Z])\w+";
   Regex regex = new Regex(pattern);
   List<string> result = new List<string>();

   foreach (string val in list)
   {
       Match match = regex.Match(val);
       result.Add(match.Value);
   }
   
   Console.Write(result);

Author

Commented:
Hi Eduard and gr8gonzo,

It works great for examples and just realized it's not work if such a case: ptrain.FrCABisch is it possible start reading from right to left ?
Fernando SotoRetired
Distinguished Expert 2017

Commented:
Hi Hakan;

The following code snippet should do what you want.
var pattern = "^.+?([a-z]+)$";
List<string> input = new List<string>() {"FRCABisch", "FrCABisch", "YTkumoty"};

foreach (string str in input)
{
    Console.WriteLine("Input string = {0} and the ending is = {1}", str, Regex.Match(str, pattern).Groups[1].Value);   
}

Open in new window

The results will be
Input string = FRCABisch and the ending is = isch
Input string = FrCABisch and the ending is = isch
Input string = YTkumoty and the ending is = kumoty

Open in new window

Commented:
It works great for examples and just realized it's not work if such a case: ptrain.FrCABisch

Why are you saying it doesn't work? It works fine for that case. It returns "isch":

        public static string GetLastLowercaseChars(string input)
        {
            var re = new Regex("[a-z]+$");
            var match = re.Match(input);
            if (match.Success)
            {
                return match.Value;
            }
            return String.Empty;
        }

Console.WriteLine(GetLastLowercaseChars("ptrain.FrCABisch")); 
// OUTPUT: "isch" 

Open in new window


If you expect something else, you might need to explain what you are expecting, because what I provided is exactly what you asked for. On a side note, all of the others that have recommended the regular expression have basically the same thing, but add unnecessary complexity. There are no group/captures necessary, or testing for word boundaries (unless you have situations where you have spaces or periods at the end). For what you've asked, the "[a-z]+$" regex is enough.

Now, if you DO want to handle additional situations like periods or spaces at the end like "FrCABisch!@.!", you could adjust it to: "([a-z]+)[^A-Z]*$" and then "return match.Groups[1].Value;" instead of "return match.Value;"


is it possible start reading from right to left ?
That is sort of what my second example does. Here's the implementation:
        public static string GetLastLowercaseCharsAlternate(string input)
        {
            for (int i = input.Length - 1; i >= 0; i--)
            {
                char c = input[i];
                if (char.IsUpper(c))
                {
                    return input.Substring(i + 1);
                }
            }
            return input;
        }

Console.WriteLine(GetLastLowercaseCharsAlternate("ptrain.FrCABisch")); 
// OUTPUT: "isch"
Console.WriteLine(GetLastLowercaseCharsAlternate("all lowercase")); 
// OUTPUT: "all lowercase"
Console.WriteLine(GetLastLowercaseCharsAlternate("ALL UPPERCASE")); 
// OUTPUT: ""

Open in new window


Again, if that's not what you want, you might need to explain more.

Author

Commented:
Hi gr8gonzo,

You're right working extremely good. Thank you.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial