How do I change all uppercase to lowercase with underscores?

There is a line in which you need to replace all identifiers of the form

SomeIdentifier

On identifiers of the form

some_identifier

Ready-made solution (works correctly):

string GetUnderScore(string source)
{
    string target = "";

    foreach (char c in source)
    {
        if (char.IsUpper(c))
        {
            target += "_" + char.ToLower(c);
        }
        else
        {
            target += c;
        }
    }
    if (target[0] == '_')
    {
        target = target.Substring(1);
    }

    return target;
}

But there's a lot of code for such a simple task. How to simplify it?

 3
c#
Author: stanislav, 2010-12-31

3 answers

You can get rid of else and the second if, and if the strings are long, it is better to use StringBuilder instead of string, because StringBuilder does not create a new string with copying characters from the previous one every time our char :)

    string GetUnderScore(string source) {
        var result = new StringBuilder(source);
        foreach (char c in source) {
            if (char.IsUpper(c) && result.Length > 0)
                result.Append("_");
            result.Append(char.ToLower(c));
        }
        return result.ToString();
    }
 2
Author: Georgy, 2010-12-31 19:02:52

Use regular expressions, they are created specifically for such tasks:

string GetUnderScore(string source)
{
    Regex pattern = new Regex(@"(?!^)(?=[A-Z])");

    return pattern.Replace(source, "_").ToLower();
}
 3
Author: stanislav, 2011-01-02 10:40:46

A large amount of code isn't always a bad thing. This function is quite short. More important is its availability for support and efficiency. The efficiency will be if you remember that strings are immutable objects (immutable), each += operator is the creation of a new object, so you need to use StringBuilder. SubString is not needed at the end, you just need to process the first letter separately at the beginning, and start the loop with 1.

 2
Author: Singlet, 2010-12-31 19:18:36