【问题标题】:Get leading whitespace获取前导空格
【发布时间】:2010-10-11 15:51:10
【问题描述】:

我刚刚写了这个方法,我想知道框架中是否已经存在类似的东西?这似乎只是其中一种方法......

如果没有,有更好的方法吗?

/// <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);
}

谢谢

编辑: 在阅读了一些 cmets 之后,很明显我还需要处理选项卡。

我不能举一个很好的例子,因为网站将空格缩小到只有一个,但我会尝试:

假设输入是一个包含 5 个空格的字符串,该方法将返回一个包含 4 个空格的字符串。如果输入少于 4 个空格,则返回 ""。 这可能会有所帮助:

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

【问题讨论】:

  • 你能提供一些示例输入/输出吗?目前尚不清楚您要从代码中做什么。例如,如果第一个字符不是空格且trimToLowerTab == false,则whitespace == 0。因此,无论行长如何,您总是以return "".PadLeft(0) 结束。如果第二个字符不是空格,你总是以 1 个空格结束,依此类推。在这些情况下,我没有看到舍入的位置。多一点上下文也会有所帮助。
  • 所以如果我给字符串" e"(想象3个空格),该方法返回的字符串应该是“”,因为只有3个空格。但如果输入字符串为" e"(5 个空格),则返回的字符串将为" "(4 个空格)(空格总数以下最接近的 4 倍数)。如果参数为假,则仅给出前导空格而不进行任何修改。编辑:该网站从 cmets 中删除了空格...
  • 您可以编辑您的问题并将您的示例作为代码放在那里吗?我在您的评论中没有看到超过一个连续的空格。
  • 你不想处理制表符吗? “空白”通常不仅仅是“空格”字符。
  • @Hightechrider:实际上,现在你提到它......我会的。现在将编辑问题

标签: c# string .net-4.0 whitespace


【解决方案1】:

我没有运行任何性能测试,但这是更少的代码。

...

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

...

【讨论】:

  • 注意:您可以删除' ' 以获取所有空格,而不仅仅是' '
  • 谢谢,这就是我要找的东西
  • @rmx - 没关系我之前的 cmets。 :) 奥斯汀的答案返回一个整数。如果您想将其转换为实际的空白,您可以执行return new string(' ', whitespace);
【解决方案2】:

您通常应该使用Char.IsWhiteSpace 而不是与' ' 进行比较。并非所有“空格”都是' '

【讨论】:

    【解决方案3】:

    我确定没有内置任何内容,但如果您对它们感到满意,您可以使用正则表达式来执行此操作。这匹配行首的任何空格:

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

    注意:这不会像简单的循环那样执行。我会选择你的实现。

    【讨论】:

    • 另外:我忽略了“4 部分的最近倍数”,因为原始问题声称它并不重要。
    【解决方案4】:

    对于其他希望将空格作为字符串获取的人,我个人认为这很简单直接:

    public static string GetLeadingWhitespace(string str)
    {
        return str.Replace(str.TrimStart(), "");
    }
    

    只需用空字符串替换所有 不是 前导空格的内容。这也适用于任何类型的空白 - 不仅仅是空格。

    【讨论】:

      【解决方案5】:

      String 的扩展方法怎么样?我传入了 tabLength 以使函数更灵活。我还添加了一个单独的方法来返回空白长度,因为您正在寻找一条评论。

      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;
      }
      

      【讨论】:

      • 非常好,谢谢。我不敢相信我没想过让它成为一种扩展方法!
      • 如果你在一个有 5 个空格的字符串上调用 GetLeadingWhitespaceLength() 会不会抛出异常?
      • 我现在没有时间调试它,但我认为它不会抛出。如果传递 SSSSSX(其中 S == 空格),则不传递第一个“if”,因此不返回零。 while 循环只计算前导空格,在这种情况下,whiteSpaceCount = 5。whiteSpaceCount (5) 不小于 tabLength (4),因此不返回零。 trimToLowerTab 为真,因此 whiteSpaceCount 减少了 whiteSpaceCount (5) % tabLength (4) (1)。所以,whiteSpaceCount 最终是 4。
      • Martin 表示它会抛出,因为对 whiteSpaceCount 没有边界检查,因此如果字符串仅包含空格,它将超出边界。 (建议进行修改以修复它。)
      • 在 while 循环的开头添加 whiteSpaceCount &lt; s.Length &amp;&amp; 来修复它。 (编辑被拒绝。)
      【解决方案6】:

      没有内置,但是怎么样:

      var result = line.TakeWhile(x => x == ' ');
      if (trimToLowerTab)
          result = result.Skip(result.Count() % 4);
      return new string(result.ToArray());
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多