【问题标题】:What method in the String class returns only the first N characters?String 类中的什么方法只返回前 N 个字符?
【发布时间】:2011-04-03 18:27:21
【问题描述】:

我想为 String 类编写一个扩展方法,这样如果输入字符串 to 长于提供的长度 N,则只显示第一个 N 字符。

如下所示:

public static string TruncateLongString(this string str, int maxLength)
{
    if (str.Length <= maxLength)
        return str;
    else
        //return the first maxLength characters                
}

我可以使用什么String.*() 方法仅获取str 的第一个N 字符?

【问题讨论】:

    标签: c# .net string character


    【解决方案1】:
    public static string TruncateLongString(this string str, int maxLength)
    {
        if (string.IsNullOrEmpty(str)) return str;
    
        return str.Substring(0, Math.Min(str.Length, maxLength));
    }
    

    在 C# 8 或更高版本中,也可以使用 Range 来使这更简洁:

    public static string TruncateLongString(this string str, int maxLength)
    {
        return str?[0..Math.Min(str.Length, maxLength)];
    }
    

    可以使用表达式体进一步简化:

    public static string TruncateLongString(this string str, int maxLength) =>
        str?[0..Math.Min(str.Length, maxLength)];
    

    注意空条件运算符 (?) 用于处理 str 为空的情况。这取代了显式空值检查的需要。

    【讨论】:

    • 需要 Math.Min 吗?我以为 Substring 知道如果第二个参数大于长度,它只是插入长度?
    • 我相信它是:System.String.InternalSubStringWithChecks 会抛出 ArgumentOutOfRange。
    • @Martin:我看不到,startIndex &gt; (this.Length - length) 抛出了一个ArgumentOutOfRangeException
    • 我会建议检查Math.Min(str.Length, maxLength) == str.Length,以防你最终创建了一个不必要的字符串来返回“str的第一个str.Length字符”,但是Substring会为你检查并且只是return this 如果您要求提供整个字符串。
    • 如果您希望扩展方法适用于可能为空的字符串...返回 str?.Substring(0, Math.Min(str.Length, maxLength));
    【解决方案2】:

    您可以使用 LINQ str.Take(n)str.SubString(0, n),后者将为 n &gt; str.Length 抛出 ArgumentOutOfRangeException 异常。

    请注意 LINQ 版本返回 IEnumerable&lt;char&gt;,因此您必须将 IEnumerable&lt;char&gt; 转换为 stringnew string(s.Take(n).ToArray())

    【讨论】:

    • 不要使用 Linq 截断字符串。这太荒谬了。
    【解决方案3】:
    string truncatedToNLength = new string(s.Take(n).ToArray());  
    

    这个解决方案有一个小小的好处,即如果 n 大于 s.Length,它仍然会做正确的事情。

    【讨论】:

    • 是的,但是使用 Linq 截断字符串?请注意,如果多次使用(例如在循环中),这将表现得非常糟糕。不要因为习惯而这样做
    • @ErikE 可能会注意到这是一次性短字符串处理的好解决方案。
    • 我同意,可读性通常比微性能更重要。当性能成为问题时,可以重新评估。大多数时候都没有关系。
    • @MattGreer 在已经存在完全清晰的String.Substring 方法的情况下使用Linq 进行子串化,正是初级开发人员认为聪明但被他们的前辈打勾的那种编码。“避免过早优化”的深层含义“正如该短语的创造者所预期的那样,实际上建议避免这个答案。字符串处理是所有计算中性能破坏的最成熟的领域之一,并且不关心性能而支持“等到出现问题”远不如认真编写不太可能出现性能问题的代码。
    【解决方案4】:
    substring(int startpos, int lenght);
    

    【讨论】:

      【解决方案5】:
      public static string TruncateLongString(this string str, int maxLength)
      {
          return str.Length <= maxLength ? str : str.Remove(maxLength);
      }
      

      【讨论】:

      • 另外,请注意,您还可以通过将条件更改为 str == null || str.Length &lt;= maxLength 来使扩展方法为空安全
      • 对于任何想知道RemoveSubstring 是否更好的人来说,没有区别。 Remove(maxLength) 只是在进行一些边界检查后调用 Substring(0,maxLength)。您更喜欢哪个取决于您是否将截断视为“获取第一个 maxLength 字符”或“丢弃 maxLength 字符之后的所有内容”。当然,这两者都是如此,所以这取决于你。
      【解决方案6】:

      string.Substring(0,n); // 0 - 起始索引和 n - 字符数

      【讨论】:

      • 与接受的答案不同,这可能导致索引越界错误。
      【解决方案7】:

      简单地说:

      public static String Truncate(String input,int maxLength)
      {
         if(input.Length > maxLength)
            return input.Substring(0,maxLength);
         return input;
      }
      

      【讨论】:

        【解决方案8】:

        如果我们在谈论验证,还有为什么我们没有检查空字符串条目。有什么具体原因吗?

        我认为以下方式会有所帮助,因为 IsNullOrEmpty 是系统定义的方法,三元运算符的圈复杂度 = 1,而 if() {} else {} 的值为 2。

            public static string Truncate(string input, int truncLength)
            {
                return (!String.IsNullOrEmpty(input) && input.Length >= truncLength)
                           ? input.Substring(0, truncLength)
                           : input;
            }
        

        【讨论】:

        • 圈复杂度 2 有什么问题?
        【解决方案9】:

        每当我必须在 C# 中进行字符串操作时,我都会怀念 Visual Basic 中的旧 LeftRight 函数,它们比 Substring 更易于使用。

        所以在我的大多数 C# 项目中,我都会为它们创建扩展方法:

        public static class StringExtensions
        {
            public static string Left(this string str, int length)
            {
                return str.Substring(0, Math.Min(length, str.Length));
            }
        
            public static string Right(this string str, int length)
            {
                return str.Substring(str.Length - Math.Min(length, str.Length));
            }
        }
        

        注意:
        Math.Min 部分之所以存在,是因为当输入字符串的长度小于请求的长度时,Substring 会抛出 ArgumentOutOfRangeException,正如之前答案中的某些 cmets 中已经提到的那样。

        用法:

        string longString = "Long String";
        
        // returns "Long";
        string left1 = longString.Left(4);
        
        // returns "Long String";
        string left2 = longString.Left(100);
        

        【讨论】:

        • 我喜欢这个,但是如果字符串比给定的长度短,它就不会附加空格。 public static string Left(this string str, int length) { var Result = str.Substring(0, Math.Min(length, str.Length)); return (Result.Length &lt; length) ? Result.PadRight(length) : Result; }
        • str 需要检查是否为空
        【解决方案10】:

        我在我的项目中添加了这个只是因为我使用它的地方很有可能在循环中使用它,在一个在线托管的项目中,因此如果我可以管理它,我不希望任何崩溃。长度适合我的列。这是 C#7

        只有一行:

         public static string SubStringN(this string Message, int Len = 499) => !String.IsNullOrEmpty(Message) ? (Message.Length >= Len ? Message.Substring(0, Len) : Message) : "";
        

        【讨论】:

          【解决方案11】:

          .NET Substring 方法充满危险。我开发了处理各种场景的扩展方法。好处是它保留了原始行为,但是当您添加一个额外的“true”参数时,它会使用扩展方法来处理异常,并根据索引和长度返回最合乎逻辑的值。例如,如果长度为负数,则向后计数。您可以在以下位置查看具有多种值的测试结果:https://dotnetfiddle.net/m1mSH9。这将使您清楚地了解它如何解析子字符串。

          我总是将这些方法添加到我的所有项目中,并且永远不必担心代码破坏,因为某些内容发生了变化并且索引无效。下面是代码。

              public static String Substring(this String val, int startIndex, bool handleIndexException)
              {
                  if (!handleIndexException)
                  { //handleIndexException is false so call the base method
                      return val.Substring(startIndex);
                  }
                  if (string.IsNullOrEmpty(val))
                  {
                      return val;
                  }
                  return val.Substring(startIndex < 0 ? 0 : startIndex > (val.Length - 1) ? val.Length : startIndex);
              }
          
              public static String Substring(this String val, int startIndex, int length, bool handleIndexException)
              {
                  if (!handleIndexException)
                  { //handleIndexException is false so call the base method
                      return val.Substring(startIndex, length);
                  }
                  if (string.IsNullOrEmpty(val))
                  {
                      return val;
                  }
                  int newfrom, newlth, instrlength = val.Length;
                  if (length < 0) //length is negative
                  {
                      newfrom = startIndex + length;
                      newlth = -1 * length;
                  }
                  else //length is positive
                  {
                      newfrom = startIndex;
                      newlth = length;
                  }
                  if (newfrom + newlth < 0 || newfrom > instrlength - 1)
                  {
                      return string.Empty;
                  }
                  if (newfrom < 0)
                  {
                      newlth = newfrom + newlth;
                      newfrom = 0;
                  }
                  return val.Substring(newfrom, Math.Min(newlth, instrlength - newfrom));
              }
          

          我早在 2010 年 5 月就在博客上写过这个:http://jagdale.blogspot.com/2010/05/substring-extension-method-that-does.html

          【讨论】:

            【解决方案12】:

            部分是为了总结(不包括 LINQ 解决方案),这里有两个单行代码来解决 int maxLength 允许负值的警告以及空字符串的情况:

            1. Substring 方式(来自Paul Ruane's answer):
            public static string Truncate(this string s, uint maxLength) =>
                s?.Substring(0, Math.Min(s.Length, (int)maxLength));
            
            1. Remove 方式(来自kbrimington's answer):
            public static string Truncate(this string s, uint maxLength) =>
                s?.Length > maxLength ? s.Remove((int)maxLength) : s;
            

            【讨论】:

              【解决方案13】:

              C# 8

              public static string TruncateLongString(this string str, int maxLength)
              {
                  if (string.IsNullOrEmpty(str)) return str;
              
                  return str[.. Math.Min(str.Length, maxLength)];
              }
              

              【讨论】:

                猜你喜欢
                • 2015-09-04
                • 2014-10-23
                • 1970-01-01
                • 2010-10-24
                • 1970-01-01
                • 2011-01-10
                • 1970-01-01
                • 2017-02-25
                • 1970-01-01
                相关资源
                最近更新 更多