views:

73

answers:

5

Hi, I just wrote this method and I'm wondering if something similar already exists in the framework? It just seems like one of those methods...

If not, is there a better way to do it?

/// <summary>
/// Return the whitespace at the start of a line.
/// </summary>
/// <param name="trimToLowerTab">Round the number of spaces down to the nearest multiple of 4.</param>
public string GetLeadingWhitespace(string line, bool trimToLowerTab = true)
{
    int whitespace = 0;
    foreach (char ch in line)
    {
        if (ch != ' ') break;
        ++whitespace;
    }

    if (trimToLowerTab)
        whitespace -= whitespace % 4;

    return "".PadLeft(whitespace);
}

Thanks

Edit: after reading some comments, Its clear that I also need to handle tabs.

I can't give a very good example because the website trims spaces down to just one but I'll try:

Say the input is a string with 5 spaces, the method will return a string with 4 spaces. If the input is less than 4 spaces, it returns "". This might help:

input spaces | output spaces
0 | 0
1 | 0
2 | 0
3 | 0
4 | 4
5 | 4
6 | 4
7 | 4
8 | 8
9 | 8
...
+2  A: 

I didn't run any performance tests but this is less code.

...

whitespace = line.Length - line.TrimStart(' ').Length;

...
Austin Salonen
Note: You can remove the `' '` to get all whitespace and not just `' '`.
Austin Salonen
Thanks this is what I was looking for
rmx
@rmx - Nevermind my earlier comments then. :) Austin's answer returns an integer. If you want to convert that to actual whitespace you can do `return new string(' ', whitespace);`
Nelson
+1  A: 

Nothing built in, but how about:

var result = line.TakeWhile(x => x == ' ');
if (trimToLowerTab)
    result = result.Skip(result.Count() % 4);
return new string(result.ToArray());
Kirk Woll
+1  A: 

You should be using Char.IsWhiteSpace instead of comparing with ' ', usually. Not all "spaces" are ' '

Craig Stuntz
+1  A: 

I'm sure there's nothing built in, but you can use a regular expression to do this if you're comfortable with them. This matches any whitespace at the beginning of the line:

public static string GetLeadingWhitespace(string line)
{
  return Regex.Match(line, @"^([\s]+)").Groups[1].Value;
}

NOTE: This would not perform as well as a simple loop. I would just go with your implementation.

steinar
Also: I'm ignoring the "nearest multiple of 4 part" as the original question claimed that it wasn't important.
steinar
+1  A: 

What about an extension method on String? I passed in the tabLength to make the function more flexible. I also added a separate method to return the whitespace length since one comment that that is what you were looking for.

public static string GetLeadingWhitespace(this string s, int tabLength = 4, bool trimToLowerTab = true)
{
  return new string(' ', s.GetLeadingWhitespaceLength());
}

public static int GetLeadingWhitespaceLength(this string s, int tabLength = 4, bool trimToLowerTab = true)
{
  if (s.Length < tabLength) return 0;

  int whiteSpaceCount = 0;

  while (Char.IsWhiteSpace(s[whiteSpaceCount])) whiteSpaceCount++;

  if (whiteSpaceCount < tabLength) return 0;

  if (trimToLowerTab)
  {
    whiteSpaceCount -= whiteSpaceCount % tabLength;
  }

  return whiteSpaceCount;
}
wageoghe
Very nice, thanks. I cant beleive i didnt think of making it an extension method!
rmx