6

I would like to add a space when an uppercase character or an underscore is in the string.

How do I do this?

EXAMPLE 1

Input

ThisIsAnInputString

Output (result)

This Is An Input String

EXAMPLE 2

Input

This_Is_An_Input_String

Output (result)

This Is An Input String
John Willemse
  • 6,608
  • 7
  • 31
  • 45
001
  • 62,807
  • 94
  • 230
  • 350
  • In the first case it is a bit tricky but I would go for the ASCII solution since there is the place to look for difference of 'U' from 'u' in second case it is just char replacement. If going for the ascii just cast char by char to int and you will get it. Here is the link to the actual ascii table : http://www.dotnetperls.com/ascii-table Sorry for not giving the solution itself but the question was how... – nzic Feb 18 '13 at 23:08
  • 1
    Try this for spaces : http://stackoverflow.com/questions/272633/add-spaces-before-capital-letters – WannaCSharp Feb 18 '13 at 23:12

6 Answers6

14

You can use a regular expression that matches a lower case character followed by an upper case character, with an optional underscore between:

string output = Regex.Replace(input, "([a-z])_?([A-Z])", "$1 $2");

You might want to use this to handle single character words also:

string output = Regex.Replace(input, "(?<!^)_?([A-Z])", " $1");
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • 2
    +1, I might change `[a-z]` to `[a-zA-Z]` to handle strings like `ThisIsATest` though. – Abe Miessler Feb 18 '13 at 23:16
  • Hrrm, can you give me an example of when it would work better? Sorry, my regex is pretty weak. – Abe Miessler Feb 18 '13 at 23:29
  • Your own example. Come to think of it `[a-z]?` should suffice. I.e: `Regex.Replace(input, "([a-z]?)_?([A-Z])", "$1 $2")`. `This_Is_A_Test` would with your example not yield a desired result. – Sani Huttunen Feb 19 '13 at 00:31
  • @SaniHuttunen: That would add a space before the first character. – Guffa Feb 19 '13 at 00:45
  • @Guffa: And according to specifications this would be correct. From OP: `add a space when an uppercase character`. That would include the first character aswell. – Sani Huttunen Feb 19 '13 at 00:48
  • Actually my example doesn't suffice either. If the input string is already in the correct state my example will fail. `([a-z]?)[_^ ]?([A-Z])` however should work. – Sani Huttunen Feb 19 '13 at 01:41
  • @SaniHuttunen: I don't think that was the intention. If you go strictly by the description, the output of the second example would be `" This _ Is _ An _ Input _ String"`. – Guffa Feb 19 '13 at 01:56
  • @Guffa: "Good intentions pave the way to hell" ;) Jokes aside, I cannot see how the second example would become what you say. See my answer for test cases. – Sani Huttunen Feb 19 '13 at 02:00
  • @SaniHuttunen: The description says to add a space when an uppercase character or an underscore is in the string. That would mean to add a space before underscores just like before uppercase characters. The second example has both uppercase characters and underscores, so there would be spaces before both of them. – Guffa Feb 19 '13 at 02:03
  • @Guffa: Aaah... You meant the OPs' second example and not mine. Yes. I agree. But still. Yours (and Abes) will still fail. Even on the example Abe brought up. – Sani Huttunen Feb 19 '13 at 02:07
  • @SaniHuttunen: Why do you think that they fail? – Guffa Feb 19 '13 at 02:10
  • @Guffa: Since `ThisIsATest` will with both yours and Abes solution yield "This Is ATest". `This_Is_A_Test` would yield `This Is A_Test`. – Sani Huttunen Feb 19 '13 at 02:15
  • @SaniHuttunen: Ah, I see what you mean. Using a negative look-behind would solve that. – Guffa Feb 19 '13 at 06:49
  • @Guffa: Almost perfect but still an already correct string will fail, `This Is A Test`. A string with a leading underscore will also fail, `_This_Is_A_Test`. – Sani Huttunen Feb 19 '13 at 07:56
  • @SaniHuttunen: I can't see that OP has any need for that. You can always find strings where the result might be unwanted, like an acronym that gets spaced; `AnSQLQuery` becomes `An S Q L Query` rather than `An SQL Query`. – Guffa Feb 19 '13 at 11:16
6

Underscores:

string inputString = "This_Is_An_Input_String";
string resultString = inputString.Replace('_', ' ');

Capitals:

string inputString = "ThisIsAnInputString";
//this will put a space before all capitals that are preceded by a lowercase character
string resultString = Regex.Replace(inputString, @"([a-z])([A-Z])", "$1 $2");
sparky68967
  • 637
  • 1
  • 5
  • 8
1

According to your specifications you want to add a space before any uppercase character. This should also apply for the first letter aswell. All underscores should be replaced with a space. Most answers here omit the first space (before This).

var pattern = "([a-z?])[_ ]?([A-Z])";

var input = "ThisIsATest";
var output = Regex.Replace(input, pattern, "$1 $2");
// output = " This Is A Test"

var input = "This_Is_A_Test";
var output = Regex.Replace(input, pattern, "$1 $2");
// output = " This Is A Test"

var input = "ThisIsAnInputString";
var output = Regex.Replace(input, pattern, "$1 $2");
// output = " This Is An Input String"

var input = "This_Is_An_Input_String";
var output = Regex.Replace(input, pattern, "$1 $2");
// output = " This Is An Input String"

If you do not want the extra space in the beginning then use TrimStart

var input = "This_Is_A_Test";
var output = Regex.Replace(input, pattern, "$1 $2").TrimStart(' ');
// output = "This Is A Test"

Edit (updated):

I've compiled the different regex suggestions into a small test application to verify the results:

static void Main(string[] args)
{
  const string expectedResult = "This Is A Test";
  var samples = new string[][]
      {
        new [] {"This Is A Test", "This Is A Test"},
        new [] {"ThisIsATest", "This Is A Test"},
        new [] {"This_Is_A_Test", "This Is A Test"},
        new [] {"ThisIsA_Test", "This Is A Test"},
        new [] {"This_IsATest", "This Is A Test"},
        new [] {"_ThisIsATest", "This Is A Test"},
        new [] {"_This_Is_A_Test", "This Is A Test"},
        new [] {"Thi_s_Is_A_Test", "Thi s Is A Test"},
        new [] {"T hi_s_Is_A_Te s_ t", "T hi s Is A Te s  t"}
      };

  foreach (var input in samples)
  {
    Console.WriteLine(input[0] + " => " + input[1]);

    // Guffa 1 1/9 correct.
    Console.WriteLine("Guffa 1:         " + (Regex.Replace(input[0], @"([a-z])_?([A-Z])", "$1 $2") == input[1]));

    // Guffa 2 4/9 correct.
    Console.WriteLine("Guffa 2:         " + (Regex.Replace(input[0], @"(?<!^)_?([A-Z])", " $1") == input[1]));

    // Abe Miesler 1/9 correct.
    Console.WriteLine("Abe Miesler:     " + (Regex.Replace(input[0], @"([a-zA-Z])_?([A-Z])", "$1 $2") == input[1]));

    // AppDeveloper 2/9 correct. (Not entirely fair since it was not meant for underscores).
    Console.WriteLine("AppDeveloper:    " + (Regex.Replace(input[0], @"_([A-Z])", " $1") == input[1]));

    // sparky68967 1/9 correct. (Not entirely fair since it was not meant for underscores).
    Console.WriteLine("sparky68967:     " + (Regex.Replace(input[0], @"([a-z])([A-Z])", "$1 $2") == input[1]));

    // p.s.w.g 4/9 correct.
    Console.WriteLine("p.s.w.g:         " + (Regex.Replace(Regex.Replace(input[0], @"([A-Z]+)([A-Z][a-z])", "$1_$2"), "_", " ") == input[1]));

    // Sani Huttunen 1 7/9 correct.
    Console.WriteLine("Sani Huttunen 1: " + (Regex.Replace(input[0], @"([a-z]?)[_ ]?([A-Z])", "$1 $2").TrimStart(' ') == input[1]));

    // Sani Huttunen 2 9/9 correct.
    Console.WriteLine("Sani Huttunen 2: " + (Regex.Replace(input[0].Replace('_', ' '), @"(?<!^)[ ]?([A-Z])", " $1").TrimStart(' ') == input[1]));

    Console.WriteLine();
  }
}
Sani Huttunen
  • 23,620
  • 6
  • 72
  • 79
0

For Input type : ThisIsAnInputString

        string input1 = "ThisIsAnInputString";
        StringBuilder builder = new StringBuilder();

        foreach (char c in input1)
        {
            if (Char.IsUpper(c))
            {
                builder.Append(' ');
                builder.Append(c);
            }
            else
            {
                builder.Append(c);
            }
        }

        string output = builder.ToString().Trim();

For Input type : This_Is_An_Input_String

string input2 = "This_Is_An_Input_String";
string output = Regex.Replace(input2, "_([A-Z])", " $1");
Parimal Raj
  • 20,189
  • 9
  • 73
  • 110
0
    // check if string is empty
        if (string.IsNullOrEmpty(input))
            return string.Empty;


        if (input.Contains('_'))
        {
            return input.Replace('_', ' ');
        }
        else
        {
            StringBuilder newString = new StringBuilder();
            foreach (Char char1 in input)
            {
                if (char.IsUpper(char1))
                    newString.Append(new char[] { ' ', char1 });
                else
                    newString.Append(char1);
            }

            newString.Remove(0, 1);
            return newString.ToString();
        }
DotNetUser
  • 6,494
  • 1
  • 25
  • 27
0
    static void Main(string[] args)
    {
        String str = "ThisIsAnInputString";
        String str2 = "This_Is_An_Input_String";

        Console.WriteLine(str);
        Console.WriteLine(str2);

        StringBuilder sb = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();

        str.ToCharArray().ToList().ForEach(c => sb.Append(c == '_' ? " " :  char.IsLower(c) ? c.ToString() : " " + c.ToString()));
        str2.ToCharArray().ToList().ForEach(c => sb2.Append(c == '_' ? " " : char.IsLower(c) ? c.ToString() : " " + c.ToString()));

        str = sb.ToString().Trim(" ".ToCharArray());
        str2 = sb2.ToString().Trim(" ".ToCharArray());

        Console.WriteLine(str);
        Console.WriteLine(str2);



        Console.Read();
    }
Swathi
  • 117
  • 1
  • 1
  • 5