2

I get the way to create space "ThisCourse" to be "This Course"

Add Space Before Capital Letter By (EtienneT) LINQ Statement

But i cannot

Create Space Betweeen This "ThisCourseID" to be "This Course ID" without space between "ID"

And Is there a way to do this in Linq ??

Community
  • 1
  • 1
Hady Shaltout
  • 606
  • 1
  • 9
  • 22

3 Answers3

8

Well, if it has to be a single linq statement...

var s = "ThisCourseIDMoreXYeahY";
s = string.Join(
        string.Empty, 
        s.Select((x,i) => (
             char.IsUpper(x) && i>0 && 
             ( char.IsLower(s[i-1]) || (i<s.Count()-1 && char.IsLower(s[i+1])) )
        ) ? " " + x : x.ToString()));
Console.WriteLine(s);

Output: "This Course ID More X Yeah Y"

HugoRune
  • 13,157
  • 7
  • 69
  • 144
4
var s = "ThisCourseID";

for (var i = 1; i < s.Length; i++)
{
    if (char.IsLower(s[i - 1]) && char.IsUpper(s[i]))
    {
        s = s.Insert(i, " ");
    }
}

Console.WriteLine(s); // "This Course ID"

You can improve this using StringBuilder if you are going to use this on very long strings, but for your purpose, as you presented it, it should work just fine.

FIX:

var s = "ThisCourseIDSomething";

for (var i = 1; i < s.Length - 1; i++)
{
    if (char.IsLower(s[i - 1]) && char.IsUpper(s[i]) ||
        s[i - 1] != ' ' && char.IsUpper(s[i]) && char.IsLower(s[i + 1]))
    {
        s = s.Insert(i, " ");
    }
}

Console.WriteLine(s); // This Course ID Something
SimpleVar
  • 14,044
  • 4
  • 38
  • 60
  • Thanks for your help Mr Yorye, Please, is there a solution to make it with LINQ ?? – Hady Shaltout Apr 01 '12 at 13:01
  • +1 for working correctly with the given sample. Note, this won't work for something like "ThisCourseIDMoreWords". The output in this case would be "This Course IDMore Words" – Robbie Apr 01 '12 at 13:08
  • @Robbie You're right, but it shouldn't be hard to play around with the condition to make it work. Fixed it. – SimpleVar Apr 01 '12 at 14:48
  • @HadyShaltout It is possible to implement the same logic with LINQ, but it would be a bad idea since LINQ isn't a tool that suits your needs in this case. – SimpleVar Apr 01 '12 at 14:51
  • 1
    @YoryeNathan i'd +1 you again but i can't :) – Robbie Apr 01 '12 at 14:52
0

You don't need LINQ - but you could 'enumerate' and use lambda to make it more generic...
(though not sure if any of this makes sense)

static IEnumerable<string> Split(this string text, Func<char?, char?, char, int?> shouldSplit)
{
    StringBuilder output = new StringBuilder();
    char? before = null;
    char? before2nd = null;
    foreach (var c in text)
    {
        var where = shouldSplit(before2nd, before, c);
        if (where != null)
        {
            var str = output.ToString();
            switch(where)
            {
                case -1:
                    output.Remove(0, str.Length -1);
                    yield return str.Substring(0, str.Length - 1);
                    break;
                case 0: default:
                    output.Clear();
                    yield return str;
                    break;
            }
        }
        output.Append(c);
        before2nd = before;
        before = c;
    }
    yield return output.ToString();
}

...and call it like this e.g. ...

    static IEnumerable<string> SplitLines(this string text)
    {
        return text.Split((before2nd, before, now) =>
        {
            if ((before2nd ?? 'A') == '\r' && (before ?? 'A') == '\n') return 0; // split on 'now'
            return null; // don't split
        });
    }
    static IEnumerable<string> SplitOnCase(this string text)
    {
        return text.Split((before2nd, before, now) =>
        {
            if (char.IsLower(before ?? 'A') && char.IsUpper(now)) return 0; // split on 'now'
            if (char.IsUpper(before2nd ?? 'a') && char.IsUpper(before ?? 'a') && char.IsLower(now)) return -1; // split one char before
            return null; // don't split
        });
    }

...and somewhere...

        var text = "ToSplitOrNotToSplitTHEQuestionIsNow";
        var words = text.SplitOnCase();
        foreach (var word in words)
            Console.WriteLine(word);

        text = "To\r\nSplit\r\nOr\r\nNot\r\nTo\r\nSplit\r\nTHE\r\nQuestion\r\nIs\r\nNow";
        words = text.SplitLines();
        foreach (var word in words)
            Console.WriteLine(word);

:)

NSGaga-mostly-inactive
  • 14,052
  • 3
  • 41
  • 51